Bug 1459785 - Update ANGLE to chromium/3396. draft
authorJeff Gilbert <jgilbert@mozilla.com>
Mon, 07 May 2018 17:38:32 -0700
changeset 798561 79db077900205b1afe71086bac85216f5979b1ea
parent 798560 33d9049f709a6e95a47798f618e6271e7ee40f73
child 798562 62b2f015612002add5ecf0f5bbb0683f9ff9d383
push id110788
push userbmo:jgilbert@mozilla.com
push dateWed, 23 May 2018 01:22:26 +0000
bugs1459785
milestone62.0a1
Bug 1459785 - Update ANGLE to chromium/3396. MozReview-Commit-ID: EA39lUfXuPI
gfx/angle/checkout/include/EGL/eglext_angle.h
gfx/angle/checkout/include/GLSLANG/ShaderLang.h
gfx/angle/checkout/include/GLSLANG/ShaderVars.h
gfx/angle/checkout/include/KHR/khrplatform.h
gfx/angle/checkout/out/gen/angle/id/commit.h
gfx/angle/checkout/src/common/Color.h
gfx/angle/checkout/src/common/FixedVector.h
gfx/angle/checkout/src/common/angleutils.h
gfx/angle/checkout/src/common/bitset_utils.h
gfx/angle/checkout/src/common/mathutil.h
gfx/angle/checkout/src/common/matrix_utils.h
gfx/angle/checkout/src/common/utilities.cpp
gfx/angle/checkout/src/common/utilities.h
gfx/angle/checkout/src/compiler/preprocessor/Tokenizer.cpp
gfx/angle/checkout/src/compiler/preprocessor/Tokenizer.l
gfx/angle/checkout/src/compiler/preprocessor/numeric_lex.h
gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.cpp
gfx/angle/checkout/src/compiler/translator/AddAndTrueToLoopCondition.cpp
gfx/angle/checkout/src/compiler/translator/AddAndTrueToLoopCondition.h
gfx/angle/checkout/src/compiler/translator/AddDefaultReturnStatements.cpp
gfx/angle/checkout/src/compiler/translator/AddDefaultReturnStatements.h
gfx/angle/checkout/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
gfx/angle/checkout/src/compiler/translator/ArrayReturnValueToOutParameter.h
gfx/angle/checkout/src/compiler/translator/BaseTypes.h
gfx/angle/checkout/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp
gfx/angle/checkout/src/compiler/translator/BreakVariableAliasingInInnerLoops.h
gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.cpp
gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.h
gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
gfx/angle/checkout/src/compiler/translator/CallDAG.cpp
gfx/angle/checkout/src/compiler/translator/ClampFragDepth.cpp
gfx/angle/checkout/src/compiler/translator/ClampFragDepth.h
gfx/angle/checkout/src/compiler/translator/ClampPointSize.cpp
gfx/angle/checkout/src/compiler/translator/ClampPointSize.h
gfx/angle/checkout/src/compiler/translator/CollectVariables.cpp
gfx/angle/checkout/src/compiler/translator/CollectVariables.h
gfx/angle/checkout/src/compiler/translator/Compiler.cpp
gfx/angle/checkout/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp
gfx/angle/checkout/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.h
gfx/angle/checkout/src/compiler/translator/DeferGlobalInitializers.cpp
gfx/angle/checkout/src/compiler/translator/DeferGlobalInitializers.h
gfx/angle/checkout/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
gfx/angle/checkout/src/compiler/translator/EmulateGLFragColorBroadcast.h
gfx/angle/checkout/src/compiler/translator/EmulatePrecision.cpp
gfx/angle/checkout/src/compiler/translator/EmulatePrecision.h
gfx/angle/checkout/src/compiler/translator/ExpandIntegerPowExpressions.cpp
gfx/angle/checkout/src/compiler/translator/ExpandIntegerPowExpressions.h
gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.h
gfx/angle/checkout/src/compiler/translator/FindMain.cpp
gfx/angle/checkout/src/compiler/translator/FindMain.h
gfx/angle/checkout/src/compiler/translator/FindSymbolNode.cpp
gfx/angle/checkout/src/compiler/translator/FindSymbolNode.h
gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.cpp
gfx/angle/checkout/src/compiler/translator/FoldExpressions.cpp
gfx/angle/checkout/src/compiler/translator/FoldExpressions.h
gfx/angle/checkout/src/compiler/translator/ImmutableString.cpp
gfx/angle/checkout/src/compiler/translator/ImmutableString.h
gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.h
gfx/angle/checkout/src/compiler/translator/InitializeVariables.cpp
gfx/angle/checkout/src/compiler/translator/InitializeVariables.h
gfx/angle/checkout/src/compiler/translator/IntermNode.cpp
gfx/angle/checkout/src/compiler/translator/IntermNode.h
gfx/angle/checkout/src/compiler/translator/IntermNodePatternMatcher.cpp
gfx/angle/checkout/src/compiler/translator/IntermNodePatternMatcher.h
gfx/angle/checkout/src/compiler/translator/IntermNode_util.cpp
gfx/angle/checkout/src/compiler/translator/IntermNode_util.h
gfx/angle/checkout/src/compiler/translator/IntermTraverse.cpp
gfx/angle/checkout/src/compiler/translator/IntermTraverse.h
gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.cpp
gfx/angle/checkout/src/compiler/translator/NodeSearch.h
gfx/angle/checkout/src/compiler/translator/OutputGLSL.cpp
gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.cpp
gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.h
gfx/angle/checkout/src/compiler/translator/OutputHLSL.cpp
gfx/angle/checkout/src/compiler/translator/OutputHLSL.h
gfx/angle/checkout/src/compiler/translator/OutputTree.cpp
gfx/angle/checkout/src/compiler/translator/ParamType.h
gfx/angle/checkout/src/compiler/translator/ParseContext.cpp
gfx/angle/checkout/src/compiler/translator/ParseContext.h
gfx/angle/checkout/src/compiler/translator/ParseContext_autogen.h
gfx/angle/checkout/src/compiler/translator/PruneNoOps.cpp
gfx/angle/checkout/src/compiler/translator/PruneNoOps.h
gfx/angle/checkout/src/compiler/translator/RecordConstantPrecision.cpp
gfx/angle/checkout/src/compiler/translator/RecordConstantPrecision.h
gfx/angle/checkout/src/compiler/translator/RegenerateStructNames.cpp
gfx/angle/checkout/src/compiler/translator/RegenerateStructNames.h
gfx/angle/checkout/src/compiler/translator/RemoveArrayLengthMethod.cpp
gfx/angle/checkout/src/compiler/translator/RemoveArrayLengthMethod.h
gfx/angle/checkout/src/compiler/translator/RemoveDynamicIndexing.cpp
gfx/angle/checkout/src/compiler/translator/RemoveDynamicIndexing.h
gfx/angle/checkout/src/compiler/translator/RemoveEmptySwitchStatements.cpp
gfx/angle/checkout/src/compiler/translator/RemoveEmptySwitchStatements.h
gfx/angle/checkout/src/compiler/translator/RemoveInvariantDeclaration.cpp
gfx/angle/checkout/src/compiler/translator/RemoveInvariantDeclaration.h
gfx/angle/checkout/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.cpp
gfx/angle/checkout/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.h
gfx/angle/checkout/src/compiler/translator/RemovePow.cpp
gfx/angle/checkout/src/compiler/translator/RemovePow.h
gfx/angle/checkout/src/compiler/translator/RemoveSwitchFallThrough.cpp
gfx/angle/checkout/src/compiler/translator/RemoveSwitchFallThrough.h
gfx/angle/checkout/src/compiler/translator/RemoveUnreferencedVariables.cpp
gfx/angle/checkout/src/compiler/translator/RemoveUnreferencedVariables.h
gfx/angle/checkout/src/compiler/translator/ReplaceVariable.cpp
gfx/angle/checkout/src/compiler/translator/ReplaceVariable.h
gfx/angle/checkout/src/compiler/translator/RewriteDoWhile.cpp
gfx/angle/checkout/src/compiler/translator/RewriteDoWhile.h
gfx/angle/checkout/src/compiler/translator/RewriteElseBlocks.cpp
gfx/angle/checkout/src/compiler/translator/RewriteElseBlocks.h
gfx/angle/checkout/src/compiler/translator/RewriteTexelFetchOffset.cpp
gfx/angle/checkout/src/compiler/translator/RewriteTexelFetchOffset.h
gfx/angle/checkout/src/compiler/translator/RewriteUnaryMinusOperatorFloat.cpp
gfx/angle/checkout/src/compiler/translator/RewriteUnaryMinusOperatorFloat.h
gfx/angle/checkout/src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp
gfx/angle/checkout/src/compiler/translator/RewriteUnaryMinusOperatorInt.h
gfx/angle/checkout/src/compiler/translator/RunAtTheEndOfShader.cpp
gfx/angle/checkout/src/compiler/translator/RunAtTheEndOfShader.h
gfx/angle/checkout/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
gfx/angle/checkout/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
gfx/angle/checkout/src/compiler/translator/SeparateArrayConstructorStatements.cpp
gfx/angle/checkout/src/compiler/translator/SeparateArrayConstructorStatements.h
gfx/angle/checkout/src/compiler/translator/SeparateArrayInitialization.cpp
gfx/angle/checkout/src/compiler/translator/SeparateArrayInitialization.h
gfx/angle/checkout/src/compiler/translator/SeparateDeclarations.cpp
gfx/angle/checkout/src/compiler/translator/SeparateDeclarations.h
gfx/angle/checkout/src/compiler/translator/SeparateExpressionsReturningArrays.cpp
gfx/angle/checkout/src/compiler/translator/SeparateExpressionsReturningArrays.h
gfx/angle/checkout/src/compiler/translator/ShaderVars.cpp
gfx/angle/checkout/src/compiler/translator/SimplifyLoopConditions.cpp
gfx/angle/checkout/src/compiler/translator/SimplifyLoopConditions.h
gfx/angle/checkout/src/compiler/translator/SplitSequenceOperator.cpp
gfx/angle/checkout/src/compiler/translator/SplitSequenceOperator.h
gfx/angle/checkout/src/compiler/translator/StaticType.cpp
gfx/angle/checkout/src/compiler/translator/StaticType.h
gfx/angle/checkout/src/compiler/translator/Symbol.cpp
gfx/angle/checkout/src/compiler/translator/Symbol.h
gfx/angle/checkout/src/compiler/translator/SymbolTable.cpp
gfx/angle/checkout/src/compiler/translator/SymbolTable.h
gfx/angle/checkout/src/compiler/translator/SymbolTable_autogen.cpp
gfx/angle/checkout/src/compiler/translator/SymbolTable_autogen.h
gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.cpp
gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.h
gfx/angle/checkout/src/compiler/translator/TranslatorESSL.cpp
gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.cpp
gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.cpp
gfx/angle/checkout/src/compiler/translator/Types.cpp
gfx/angle/checkout/src/compiler/translator/Types.h
gfx/angle/checkout/src/compiler/translator/UnfoldShortCircuitAST.cpp
gfx/angle/checkout/src/compiler/translator/UnfoldShortCircuitAST.h
gfx/angle/checkout/src/compiler/translator/UnfoldShortCircuitToIf.cpp
gfx/angle/checkout/src/compiler/translator/UnfoldShortCircuitToIf.h
gfx/angle/checkout/src/compiler/translator/UseInterfaceBlockFields.cpp
gfx/angle/checkout/src/compiler/translator/UseInterfaceBlockFields.h
gfx/angle/checkout/src/compiler/translator/UtilsHLSL.cpp
gfx/angle/checkout/src/compiler/translator/UtilsHLSL.h
gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.cpp
gfx/angle/checkout/src/compiler/translator/ValidateLimitations.cpp
gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.cpp
gfx/angle/checkout/src/compiler/translator/ValidateOutputs.cpp
gfx/angle/checkout/src/compiler/translator/ValidateSwitch.cpp
gfx/angle/checkout/src/compiler/translator/ValidateSwitch.h
gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.cpp
gfx/angle/checkout/src/compiler/translator/VectorizeVectorScalarArithmetic.cpp
gfx/angle/checkout/src/compiler/translator/VectorizeVectorScalarArithmetic.h
gfx/angle/checkout/src/compiler/translator/VersionGLSL.cpp
gfx/angle/checkout/src/compiler/translator/VersionGLSL.h
gfx/angle/checkout/src/compiler/translator/WrapSwitchStatementsInBlocks.cpp
gfx/angle/checkout/src/compiler/translator/WrapSwitchStatementsInBlocks.h
gfx/angle/checkout/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp
gfx/angle/checkout/src/compiler/translator/glslang.y
gfx/angle/checkout/src/compiler/translator/glslang_tab.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/AddAndTrueToLoopCondition.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/AddAndTrueToLoopCondition.h
gfx/angle/checkout/src/compiler/translator/tree_ops/AddDefaultReturnStatements.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/AddDefaultReturnStatements.h
gfx/angle/checkout/src/compiler/translator/tree_ops/ArrayReturnValueToOutParameter.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/ArrayReturnValueToOutParameter.h
gfx/angle/checkout/src/compiler/translator/tree_ops/BreakVariableAliasingInInnerLoops.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/BreakVariableAliasingInInnerLoops.h
gfx/angle/checkout/src/compiler/translator/tree_ops/ClampFragDepth.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/ClampFragDepth.h
gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.h
gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h
gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.h
gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.h
gfx/angle/checkout/src/compiler/translator/tree_ops/EmulatePrecision.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/EmulatePrecision.h
gfx/angle/checkout/src/compiler/translator/tree_ops/ExpandIntegerPowExpressions.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/ExpandIntegerPowExpressions.h
gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.h
gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.h
gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.h
gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RegenerateStructNames.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RegenerateStructNames.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RemovePow.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RemovePow.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveSwitchFallThrough.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveSwitchFallThrough.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDoWhile.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDoWhile.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteElseBlocks.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteElseBlocks.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteUnaryMinusOperatorFloat.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteUnaryMinusOperatorFloat.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteUnaryMinusOperatorInt.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteUnaryMinusOperatorInt.h
gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.h
gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateArrayConstructorStatements.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateArrayConstructorStatements.h
gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateArrayInitialization.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateArrayInitialization.h
gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.h
gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateExpressionsReturningArrays.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateExpressionsReturningArrays.h
gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.h
gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.h
gfx/angle/checkout/src/compiler/translator/tree_ops/UnfoldShortCircuitAST.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/UnfoldShortCircuitAST.h
gfx/angle/checkout/src/compiler/translator/tree_ops/UnfoldShortCircuitToIf.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/UnfoldShortCircuitToIf.h
gfx/angle/checkout/src/compiler/translator/tree_ops/UseInterfaceBlockFields.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/UseInterfaceBlockFields.h
gfx/angle/checkout/src/compiler/translator/tree_ops/VectorizeVectorScalarArithmetic.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/VectorizeVectorScalarArithmetic.h
gfx/angle/checkout/src/compiler/translator/tree_ops/WrapSwitchStatementsInBlocks.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/WrapSwitchStatementsInBlocks.h
gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_autogen.h
gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.cpp
gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.h
gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.cpp
gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.h
gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.cpp
gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.h
gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.cpp
gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.h
gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.cpp
gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.h
gfx/angle/checkout/src/compiler/translator/tree_util/NodeSearch.h
gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.cpp
gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.h
gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.cpp
gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.h
gfx/angle/checkout/src/libANGLE/BinaryStream.h
gfx/angle/checkout/src/libANGLE/Buffer.cpp
gfx/angle/checkout/src/libANGLE/Buffer.h
gfx/angle/checkout/src/libANGLE/Caps.cpp
gfx/angle/checkout/src/libANGLE/Caps.h
gfx/angle/checkout/src/libANGLE/Compiler.cpp
gfx/angle/checkout/src/libANGLE/Compiler.h
gfx/angle/checkout/src/libANGLE/Context.cpp
gfx/angle/checkout/src/libANGLE/Context.h
gfx/angle/checkout/src/libANGLE/ContextState.cpp
gfx/angle/checkout/src/libANGLE/ContextState.h
gfx/angle/checkout/src/libANGLE/Context_gles_1_0.cpp
gfx/angle/checkout/src/libANGLE/Context_gles_1_0_autogen.h
gfx/angle/checkout/src/libANGLE/Display.cpp
gfx/angle/checkout/src/libANGLE/Error.h
gfx/angle/checkout/src/libANGLE/Error.inl
gfx/angle/checkout/src/libANGLE/ErrorStrings.h
gfx/angle/checkout/src/libANGLE/Framebuffer.cpp
gfx/angle/checkout/src/libANGLE/Framebuffer.h
gfx/angle/checkout/src/libANGLE/FramebufferAttachment.cpp
gfx/angle/checkout/src/libANGLE/FramebufferAttachment.h
gfx/angle/checkout/src/libANGLE/GLES1State.cpp
gfx/angle/checkout/src/libANGLE/GLES1State.h
gfx/angle/checkout/src/libANGLE/HandleAllocator.cpp
gfx/angle/checkout/src/libANGLE/Image.cpp
gfx/angle/checkout/src/libANGLE/ImageIndex.cpp
gfx/angle/checkout/src/libANGLE/ImageIndex.h
gfx/angle/checkout/src/libANGLE/MemoryProgramCache.cpp
gfx/angle/checkout/src/libANGLE/Observer.cpp
gfx/angle/checkout/src/libANGLE/Observer.h
gfx/angle/checkout/src/libANGLE/PackedGLEnums.cpp
gfx/angle/checkout/src/libANGLE/PackedGLEnums.h
gfx/angle/checkout/src/libANGLE/PackedGLEnums_autogen.cpp
gfx/angle/checkout/src/libANGLE/PackedGLEnums_autogen.h
gfx/angle/checkout/src/libANGLE/Program.cpp
gfx/angle/checkout/src/libANGLE/Program.h
gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.cpp
gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.h
gfx/angle/checkout/src/libANGLE/RefCountObject.h
gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp
gfx/angle/checkout/src/libANGLE/ResourceManager.cpp
gfx/angle/checkout/src/libANGLE/ResourceManager.h
gfx/angle/checkout/src/libANGLE/Shader.cpp
gfx/angle/checkout/src/libANGLE/Shader.h
gfx/angle/checkout/src/libANGLE/State.cpp
gfx/angle/checkout/src/libANGLE/State.h
gfx/angle/checkout/src/libANGLE/Stream.cpp
gfx/angle/checkout/src/libANGLE/Surface.cpp
gfx/angle/checkout/src/libANGLE/Texture.cpp
gfx/angle/checkout/src/libANGLE/Texture.h
gfx/angle/checkout/src/libANGLE/TransformFeedback.cpp
gfx/angle/checkout/src/libANGLE/TransformFeedback.h
gfx/angle/checkout/src/libANGLE/Uniform.cpp
gfx/angle/checkout/src/libANGLE/Uniform.h
gfx/angle/checkout/src/libANGLE/VaryingPacking.cpp
gfx/angle/checkout/src/libANGLE/VertexArray.cpp
gfx/angle/checkout/src/libANGLE/VertexArray.h
gfx/angle/checkout/src/libANGLE/VertexAttribute.cpp
gfx/angle/checkout/src/libANGLE/VertexAttribute.h
gfx/angle/checkout/src/libANGLE/angletypes.cpp
gfx/angle/checkout/src/libANGLE/angletypes.h
gfx/angle/checkout/src/libANGLE/entry_points_enum_autogen.h
gfx/angle/checkout/src/libANGLE/es3_copy_conversion_table_autogen.cpp
gfx/angle/checkout/src/libANGLE/format_map_autogen.cpp
gfx/angle/checkout/src/libANGLE/formatutils.cpp
gfx/angle/checkout/src/libANGLE/formatutils.h
gfx/angle/checkout/src/libANGLE/params.cpp
gfx/angle/checkout/src/libANGLE/params.h
gfx/angle/checkout/src/libANGLE/queryconversions.cpp
gfx/angle/checkout/src/libANGLE/queryutils.cpp
gfx/angle/checkout/src/libANGLE/queryutils.h
gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.h
gfx/angle/checkout/src/libANGLE/renderer/Format.h
gfx/angle/checkout/src/libANGLE/renderer/Format_ID_autogen.inl
gfx/angle/checkout/src/libANGLE/renderer/Format_table_autogen.cpp
gfx/angle/checkout/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h
gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.h
gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.h
gfx/angle/checkout/src/libANGLE/renderer/RenderTargetCache.h
gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.cpp
gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.h
gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureStorage.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h
gfx/angle/checkout/src/libANGLE/renderer/load_functions_table_autogen.cpp
gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.cpp
gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.h
gfx/angle/checkout/src/libANGLE/signal_utils.cpp
gfx/angle/checkout/src/libANGLE/signal_utils.h
gfx/angle/checkout/src/libANGLE/validationEGL.cpp
gfx/angle/checkout/src/libANGLE/validationES.cpp
gfx/angle/checkout/src/libANGLE/validationES.h
gfx/angle/checkout/src/libANGLE/validationES1.cpp
gfx/angle/checkout/src/libANGLE/validationES1.h
gfx/angle/checkout/src/libANGLE/validationES2.cpp
gfx/angle/checkout/src/libANGLE/validationES2.h
gfx/angle/checkout/src/libANGLE/validationES3.cpp
gfx/angle/checkout/src/libANGLE/validationES3.h
gfx/angle/checkout/src/libANGLE/validationES31.cpp
gfx/angle/checkout/src/libANGLE/validationES31.h
gfx/angle/checkout/src/libGLESv2/entry_points_egl.cpp
gfx/angle/checkout/src/libGLESv2/entry_points_gles_1_0_autogen.cpp
gfx/angle/checkout/src/libGLESv2/entry_points_gles_1_0_autogen.h
gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_autogen.h
gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_ext.cpp
gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_0_autogen.cpp
gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_1_autogen.cpp
gfx/angle/checkout/src/libGLESv2/entry_points_gles_ext_autogen.cpp
gfx/angle/checkout/src/libGLESv2/entry_points_gles_ext_autogen.h
gfx/angle/checkout/src/libGLESv2/proc_table.h
gfx/angle/checkout/src/third_party/compiler/ArrayBoundsClamper.cpp
gfx/angle/targets/libANGLE/moz.build
gfx/angle/targets/translator/moz.build
--- a/gfx/angle/checkout/include/EGL/eglext_angle.h
+++ b/gfx/angle/checkout/include/EGL/eglext_angle.h
@@ -170,11 +170,16 @@ EGLAPI EGLint EGLAPIENTRY eglProgramCach
 #define EGL_ANGLE_iosurface_client_buffer 1
 #define EGL_IOSURFACE_ANGLE 0x3454
 #define EGL_IOSURFACE_PLANE_ANGLE 0x345A
 #define EGL_TEXTURE_RECTANGLE_ANGLE 0x345B
 #define EGL_TEXTURE_TYPE_ANGLE 0x345C
 #define EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D
 #endif /* EGL_ANGLE_iosurface_client_buffer */
 
+#ifndef EGL_ANGLE_create_context_extensions_enabled
+#define EGL_ANGLE_create_context_extensions_enabled 1
+#define EGL_EXTENSIONS_ENABLED_ANGLE 0x345F
+#endif /* EGL_ANGLE_create_context_extensions_enabled */
+
 // clang-format on
 
 #endif  // INCLUDE_EGL_EGLEXT_ANGLE_
--- a/gfx/angle/checkout/include/GLSLANG/ShaderLang.h
+++ b/gfx/angle/checkout/include/GLSLANG/ShaderLang.h
@@ -20,17 +20,17 @@
 // and the shading language compiler.
 //
 
 // Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
 #include "ShaderVars.h"
 
 // Version number for shader translation API.
 // It is incremented every time the API changes.
-#define ANGLE_SH_VERSION 196
+#define ANGLE_SH_VERSION 197
 
 enum ShShaderSpec
 {
     SH_GLES2_SPEC,
     SH_WEBGL_SPEC,
 
     SH_GLES3_SPEC,
     SH_WEBGL2_SPEC,
--- a/gfx/angle/checkout/include/GLSLANG/ShaderVars.h
+++ b/gfx/angle/checkout/include/GLSLANG/ShaderVars.h
@@ -121,17 +121,22 @@ struct ShaderVariable
     // Offset of this variable in parent arrays. In case the parent is an array of arrays, the
     // offset is outerArrayElement * innerArraySize + innerArrayElement.
     // For example, if there's a variable declared as size 3 array of size 4 array of int:
     //   int a[3][4];
     // then the flattenedOffsetInParentArrays of a[2] would be 2.
     // and flattenedOffsetInParentArrays of a[2][1] would be 2*4 + 1 = 9.
     unsigned int flattenedOffsetInParentArrays;
 
+    // Static use means that the variable is accessed somewhere in the shader source.
     bool staticUse;
+    // A variable is active unless the compiler determined that it is not accessed by the shader.
+    // All active variables are statically used, but not all statically used variables are
+    // necessarily active. GLES 3.0.5 section 2.12.6. GLES 3.1 section 7.3.1.
+    bool active;
     std::vector<ShaderVariable> fields;
     std::string structName;
 
   protected:
     bool isSameVariableAtLinkTime(const ShaderVariable &other,
                                   bool matchPrecision,
                                   bool matchName) const;
 
@@ -274,16 +279,17 @@ struct InterfaceBlock
     BlockLayoutType layout;
 
     // Deprecated. Matrix packing should only be queried from individual fields of the block.
     // TODO(oetuaho): Remove this once it is no longer used in Chromium.
     bool isRowMajorLayout;
 
     int binding;
     bool staticUse;
+    bool active;
     BlockType blockType;
     std::vector<InterfaceBlockField> fields;
 };
 
 struct WorkGroupSize
 {
     // Must have a trivial default constructor since it is used in YYSTYPE.
     WorkGroupSize() = default;
--- a/gfx/angle/checkout/include/KHR/khrplatform.h
+++ b/gfx/angle/checkout/include/KHR/khrplatform.h
@@ -1,13 +1,13 @@
 #ifndef __khrplatform_h_
 #define __khrplatform_h_
 
 /*
-** Copyright (c) 2008-2009 The Khronos Group Inc.
+** Copyright (c) 2008-2018 The Khronos Group Inc.
 **
 ** Permission is hereby granted, free of charge, to any person obtaining a
 ** copy of this software and/or associated documentation files (the
 ** "Materials"), to deal in the Materials without restriction, including
 ** without limitation the rights to use, copy, modify, merge, publish,
 ** distribute, sublicense, and/or sell copies of the Materials, and to
 ** permit persons to whom the Materials are furnished to do so, subject to
 ** the following conditions:
@@ -21,28 +21,26 @@
 ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 */
 
 /* Khronos platform-specific types and definitions.
  *
- * $Revision: 32517 $ on $Date: 2016-03-11 02:41:19 -0800 (Fri, 11 Mar 2016) $
+ * The master copy of khrplatform.h is maintained in the Khronos EGL
+ * Registry repository at https://github.com/KhronosGroup/EGL-Registry
+ * The last semantic modification to khrplatform.h was at commit ID:
+ *      67a3e0864c2d75ea5287b9f3d2eb74a745936692
  *
  * Adopters may modify this file to suit their platform. Adopters are
  * encouraged to submit platform specific modifications to the Khronos
  * group so that they can be included in future versions of this file.
- * Please submit changes by sending them to the public Khronos Bugzilla
- * (http://khronos.org/bugzilla) by filing a bug against product
- * "Khronos (general)" component "Registry".
- *
- * A predefined template which fills in some of the bug fields can be
- * reached using http://tinyurl.com/khrplatform-h-bugreport, but you
- * must create a Bugzilla login first.
+ * Please submit changes by filing pull requests or issues on
+ * the EGL Registry repository linked above.
  *
  *
  * See the Implementer's Guidelines for information about where this file
  * should be located on your system and for more details of its use:
  *    http://www.khronos.org/registry/implementers_guide.pdf
  *
  * This file should be included as
  *        #include <KHR/khrplatform.h>
@@ -97,18 +95,17 @@
  *-------------------------------------------------------------------------
  * This precedes the return type of the function in the function prototype.
  */
 #if defined(_WIN32) && !defined(__SCITECH_SNAP__)
 #   define KHRONOS_APICALL __declspec(dllimport)
 #elif defined (__SYMBIAN32__)
 #   define KHRONOS_APICALL IMPORT_C
 #elif defined(__ANDROID__)
-#   include <sys/cdefs.h>
-#   define KHRONOS_APICALL __attribute__((visibility("default"))) __NDK_FPABI__
+#   define KHRONOS_APICALL __attribute__((visibility("default")))
 #else
 #   define KHRONOS_APICALL
 #endif
 
 /*-------------------------------------------------------------------------
  * Definition of KHRONOS_APIENTRY
  *-------------------------------------------------------------------------
  * This follows the return type of the function  and precedes the function
@@ -277,9 +274,9 @@ typedef khronos_int64_t        khronos_s
  * comparisons should not be made against KHRONOS_TRUE.
  */
 typedef enum {
     KHRONOS_FALSE = 0,
     KHRONOS_TRUE  = 1,
     KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
 } khronos_boolean_enum_t;
 
-#endif /* __khrplatform_h_ */
\ No newline at end of file
+#endif /* __khrplatform_h_ */
--- a/gfx/angle/checkout/out/gen/angle/id/commit.h
+++ b/gfx/angle/checkout/out/gen/angle/id/commit.h
@@ -1,3 +1,3 @@
-#define ANGLE_COMMIT_HASH "fcbca0e873c3"
+#define ANGLE_COMMIT_HASH "2426b097472f"
 #define ANGLE_COMMIT_HASH_SIZE 12
-#define ANGLE_COMMIT_DATE "2018-04-20 16:07:35 -0700"
+#define ANGLE_COMMIT_DATE "2018-05-22 15:14:46 -0700"
--- a/gfx/angle/checkout/src/common/Color.h
+++ b/gfx/angle/checkout/src/common/Color.h
@@ -10,23 +10,26 @@
 #define COMMON_COLOR_H_
 
 namespace angle
 {
 
 template <typename T>
 struct Color
 {
+    Color();
+    Color(T r, T g, T b, T a);
+
+    const T *data() const { return &red; }
+    T *ptr() { return &red; }
+
     T red;
     T green;
     T blue;
     T alpha;
-
-    Color();
-    Color(T r, T g, T b, T a);
 };
 
 template <typename T>
 bool operator==(const Color<T> &a, const Color<T> &b);
 
 template <typename T>
 bool operator!=(const Color<T> &a, const Color<T> &b);
 
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/common/FixedVector.h
@@ -0,0 +1,331 @@
+//
+// 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.
+//
+// FixedVector.h:
+//   A vector class with a maximum size and fixed storage.
+//
+
+#ifndef COMMON_FIXEDVECTOR_H_
+#define COMMON_FIXEDVECTOR_H_
+
+#include "common/debug.h"
+
+#include <algorithm>
+#include <array>
+#include <initializer_list>
+
+namespace angle
+{
+template <class T, size_t N, class Storage = std::array<T, N>>
+class FixedVector final
+{
+  public:
+    using value_type             = typename Storage::value_type;
+    using size_type              = typename Storage::size_type;
+    using reference              = typename Storage::reference;
+    using const_reference        = typename Storage::const_reference;
+    using pointer                = typename Storage::pointer;
+    using const_pointer          = typename Storage::const_pointer;
+    using iterator               = typename Storage::iterator;
+    using const_iterator         = typename Storage::const_iterator;
+    using reverse_iterator       = typename Storage::reverse_iterator;
+    using const_reverse_iterator = typename Storage::const_reverse_iterator;
+
+    FixedVector();
+    FixedVector(size_type count, const value_type &value);
+    FixedVector(size_type count);
+
+    FixedVector(const FixedVector<T, N, Storage> &other);
+    FixedVector(FixedVector<T, N, Storage> &&other);
+    FixedVector(std::initializer_list<value_type> init);
+
+    FixedVector<T, N, Storage> &operator=(const FixedVector<T, N, Storage> &other);
+    FixedVector<T, N, Storage> &operator=(FixedVector<T, N, Storage> &&other);
+    FixedVector<T, N, Storage> &operator=(std::initializer_list<value_type> init);
+
+    ~FixedVector();
+
+    reference at(size_type pos);
+    const_reference at(size_type pos) const;
+
+    reference operator[](size_type pos);
+    const_reference operator[](size_type pos) const;
+
+    pointer data();
+    const_pointer data() const;
+
+    iterator begin();
+    const_iterator begin() const;
+
+    iterator end();
+    const_iterator end() const;
+
+    bool empty() const;
+    size_type size() const;
+    size_type max_size() const;
+
+    void clear();
+
+    void push_back(const value_type &value);
+    void push_back(value_type &&value);
+
+    void pop_back();
+    reference back();
+    const_reference back() const;
+
+    void swap(FixedVector<T, N, Storage> &other);
+
+    void resize(size_type count);
+    void resize(size_type count, const value_type &value);
+
+    bool full() const;
+
+  private:
+    void assign_from_initializer_list(std::initializer_list<value_type> init);
+
+    Storage mStorage;
+    size_type mSize = 0;
+};
+
+template <class T, size_t N, class Storage>
+bool operator==(const FixedVector<T, N, Storage> &a, const FixedVector<T, N, Storage> &b)
+{
+    return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
+}
+
+template <class T, size_t N, class Storage>
+bool operator!=(const FixedVector<T, N, Storage> &a, const FixedVector<T, N, Storage> &b)
+{
+    return !(a == b);
+}
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector() = default;
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector(size_type count, const value_type &value) : mSize(count)
+{
+    ASSERT(count <= N);
+    std::fill(mStorage.begin(), mStorage.begin() + count, value);
+}
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector(size_type count) : mSize(count)
+{
+    ASSERT(count <= N);
+}
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector(const FixedVector<T, N, Storage> &other) = default;
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector(FixedVector<T, N, Storage> &&other) = default;
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector(std::initializer_list<value_type> init)
+{
+    ASSERT(init.size() <= N);
+    assign_from_initializer_list(init);
+}
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage> &FixedVector<T, N, Storage>::operator=(
+    const FixedVector<T, N, Storage> &other) = default;
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage> &FixedVector<T, N, Storage>::operator=(
+    FixedVector<T, N, Storage> &&other) = default;
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage> &FixedVector<T, N, Storage>::operator=(
+    std::initializer_list<value_type> init)
+{
+    clear();
+    ASSERT(init.size() <= N);
+    assign_from_initializer_list(init);
+    return this;
+}
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::~FixedVector()
+{
+    clear();
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::reference FixedVector<T, N, Storage>::at(size_type pos)
+{
+    ASSERT(pos < N);
+    return mStorage.at(pos);
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_reference FixedVector<T, N, Storage>::at(
+    size_type pos) const
+{
+    ASSERT(pos < N);
+    return mStorage.at(pos);
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::reference FixedVector<T, N, Storage>::operator[](size_type pos)
+{
+    ASSERT(pos < N);
+    return mStorage[pos];
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_reference FixedVector<T, N, Storage>::operator[](
+    size_type pos) const
+{
+    ASSERT(pos < N);
+    return mStorage[pos];
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_pointer angle::FixedVector<T, N, Storage>::data() const
+{
+    return mStorage.data();
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::pointer angle::FixedVector<T, N, Storage>::data()
+{
+    return mStorage.data();
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::iterator FixedVector<T, N, Storage>::begin()
+{
+    return mStorage.begin();
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_iterator FixedVector<T, N, Storage>::begin() const
+{
+    return mStorage.begin();
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::iterator FixedVector<T, N, Storage>::end()
+{
+    return mStorage.begin() + mSize;
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_iterator FixedVector<T, N, Storage>::end() const
+{
+    return mStorage.begin() + mSize;
+}
+
+template <class T, size_t N, class Storage>
+bool FixedVector<T, N, Storage>::empty() const
+{
+    return mSize == 0;
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::size_type FixedVector<T, N, Storage>::size() const
+{
+    return mSize;
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::size_type FixedVector<T, N, Storage>::max_size() const
+{
+    return N;
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::clear()
+{
+    resize(0);
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::push_back(const value_type &value)
+{
+    ASSERT(mSize < N);
+    mStorage[mSize] = value;
+    mSize++;
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::push_back(value_type &&value)
+{
+    ASSERT(mSize < N);
+    mStorage[mSize] = std::move(value);
+    mSize++;
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::pop_back()
+{
+    ASSERT(mSize > 0);
+    mSize--;
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::reference FixedVector<T, N, Storage>::back()
+{
+    ASSERT(mSize > 0);
+    return mStorage[mSize - 1];
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_reference FixedVector<T, N, Storage>::back() const
+{
+    ASSERT(mSize > 0);
+    return mStorage[mSize - 1];
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::swap(FixedVector<T, N, Storage> &other)
+{
+    std::swap(mSize, other.mSize);
+    std::swap(mStorage, other.mStorage);
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::resize(size_type count)
+{
+    resize(count, value_type());
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::resize(size_type count, const value_type &value)
+{
+    ASSERT(count <= N);
+    while (mSize > count)
+    {
+        mSize--;
+        mStorage[mSize] = T();
+    }
+    while (mSize < count)
+    {
+        mStorage[mSize] = value;
+        mSize++;
+    }
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::assign_from_initializer_list(
+    std::initializer_list<value_type> init)
+{
+    for (auto element : init)
+    {
+        mStorage[mSize] = std::move(element);
+        mSize++;
+    }
+}
+
+template <class T, size_t N, class Storage>
+bool FixedVector<T, N, Storage>::full() const
+{
+    return (mSize == N);
+}
+}  // namespace angle
+
+#endif  // COMMON_FIXEDVECTOR_H_
--- a/gfx/angle/checkout/src/common/angleutils.h
+++ b/gfx/angle/checkout/src/common/angleutils.h
@@ -186,16 +186,17 @@ std::string ToString(const T &value)
     return o.str();
 }
 
 // snprintf is not defined with MSVC prior to to msvc14
 #if defined(_MSC_VER) && _MSC_VER < 1900
 #define snprintf _snprintf
 #endif
 
+#define GL_A1RGB5_ANGLEX 0x6AC5
 #define GL_BGRX8_ANGLEX 0x6ABA
 #define GL_BGR565_ANGLEX 0x6ABB
 #define GL_BGRA4_ANGLEX 0x6ABC
 #define GL_BGR5_A1_ANGLEX 0x6ABD
 #define GL_INT_64_ANGLEX 0x6ABE
 #define GL_UINT_64_ANGLEX 0x6ABF
 #define GL_BGRA8_SRGB_ANGLEX 0x6AC0
 
--- a/gfx/angle/checkout/src/common/bitset_utils.h
+++ b/gfx/angle/checkout/src/common/bitset_utils.h
@@ -35,20 +35,20 @@ class BitSetT final
             mParent->set(mBit, x);
             return *this;
         }
         explicit operator bool() const { return mParent->test(mBit); }
 
       private:
         friend class BitSetT;
 
-        Reference(BitSetT *parent, std::size_t bit) : mParent(parent), mBit(bit) {}
+        Reference(BitSetT *parent, ParamT bit) : mParent(parent), mBit(bit) {}
 
         BitSetT *mParent;
-        std::size_t mBit;
+        ParamT mBit;
     };
 
     class Iterator final
     {
       public:
         Iterator(const BitSetT &bits);
         Iterator &operator++();
 
@@ -59,18 +59,17 @@ class BitSetT final
       private:
         std::size_t getNextBit();
 
         BitSetT mBitsCopy;
         std::size_t mCurrentBit;
     };
 
     BitSetT();
-    BitSetT(BitsT value);
-    ~BitSetT();
+    constexpr explicit BitSetT(BitsT value);
 
     BitSetT(const BitSetT &other);
     BitSetT &operator=(const BitSetT &other);
 
     bool operator==(const BitSetT &other) const;
     bool operator!=(const BitSetT &other) const;
 
     constexpr bool operator[](ParamT pos) const;
@@ -85,16 +84,20 @@ class BitSetT final
 
     constexpr std::size_t size() const { return N; }
 
     BitSetT &operator&=(const BitSetT &other);
     BitSetT &operator|=(const BitSetT &other);
     BitSetT &operator^=(const BitSetT &other);
     BitSetT operator~() const;
 
+    BitSetT &operator&=(BitsT value);
+    BitSetT &operator|=(BitsT value);
+    BitSetT &operator^=(BitsT value);
+
     BitSetT operator<<(std::size_t pos) const;
     BitSetT &operator<<=(std::size_t pos);
     BitSetT operator>>(std::size_t pos) const;
     BitSetT &operator>>=(std::size_t pos);
 
     BitSetT &set();
     BitSetT &set(ParamT pos, bool value = true);
 
@@ -110,17 +113,21 @@ class BitSetT final
     Iterator begin() const { return Iterator(*this); }
     Iterator end() const { return Iterator(BitSetT()); }
 
   private:
     constexpr static BitsT Bit(ParamT x)
     {
         return (static_cast<BitsT>(1) << static_cast<size_t>(x));
     }
-    constexpr static BitsT Mask(std::size_t x) { return ((Bit(x - 1) - 1) << 1) + 1; }
+    // Produces a mask of ones up to the "x"th bit.
+    constexpr static BitsT Mask(std::size_t x)
+    {
+        return ((Bit(static_cast<ParamT>(x - 1)) - 1) << 1) + 1;
+    }
 
     BitsT mBits;
 };
 
 template <size_t N>
 class IterableBitSet : public std::bitset<N>
 {
   public:
@@ -208,22 +215,17 @@ unsigned long IterableBitSet<N>::Iterato
 template <size_t N, typename BitsT, typename ParamT>
 BitSetT<N, BitsT, ParamT>::BitSetT() : mBits(0)
 {
     static_assert(N > 0, "Bitset type cannot support zero bits.");
     static_assert(N <= sizeof(BitsT) * 8, "Bitset type cannot support a size this large.");
 }
 
 template <size_t N, typename BitsT, typename ParamT>
-BitSetT<N, BitsT, ParamT>::BitSetT(BitsT value) : mBits(value & Mask(N))
-{
-}
-
-template <size_t N, typename BitsT, typename ParamT>
-BitSetT<N, BitsT, ParamT>::~BitSetT()
+constexpr BitSetT<N, BitsT, ParamT>::BitSetT(BitsT value) : mBits(value & Mask(N))
 {
 }
 
 template <size_t N, typename BitsT, typename ParamT>
 BitSetT<N, BitsT, ParamT>::BitSetT(const BitSetT &other) : mBits(other.mBits)
 {
 }
 
@@ -308,16 +310,37 @@ BitSetT<N, BitsT, ParamT> &BitSetT<N, Bi
 
 template <size_t N, typename BitsT, typename ParamT>
 BitSetT<N, BitsT, ParamT> BitSetT<N, BitsT, ParamT>::operator~() const
 {
     return BitSetT<N, BitsT, ParamT>(~mBits & Mask(N));
 }
 
 template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator&=(BitsT value)
+{
+    mBits &= value;
+    return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator|=(BitsT value)
+{
+    mBits |= value;
+    return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator^=(BitsT value)
+{
+    mBits ^= value;
+    return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
 BitSetT<N, BitsT, ParamT> BitSetT<N, BitsT, ParamT>::operator<<(std::size_t pos) const
 {
     return BitSetT<N, BitsT, ParamT>((mBits << pos) & Mask(N));
 }
 
 template <size_t N, typename BitsT, typename ParamT>
 BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator<<=(std::size_t pos)
 {
--- a/gfx/angle/checkout/src/common/mathutil.h
+++ b/gfx/angle/checkout/src/common/mathutil.h
@@ -4,57 +4,59 @@
 // found in the LICENSE file.
 //
 
 // mathutil.h: Math and bit manipulation functions.
 
 #ifndef COMMON_MATHUTIL_H_
 #define COMMON_MATHUTIL_H_
 
-#include <limits>
-#include <algorithm>
 #include <math.h>
-#include <string.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <string.h>
+#include <algorithm>
+#include <limits>
 
 #include <anglebase/numerics/safe_math.h>
 
 #include "common/debug.h"
 #include "common/platform.h"
 
 namespace angle
 {
 using base::CheckedNumeric;
 using base::IsValueInRangeForNumericType;
 }
 
 namespace gl
 {
 
-const unsigned int Float32One = 0x3F800000;
+const unsigned int Float32One   = 0x3F800000;
 const unsigned short Float16One = 0x3C00;
 
-template<typename T>
+template <typename T>
 inline bool isPow2(T x)
 {
     static_assert(std::is_integral<T>::value, "isPow2 must be called on an integer type.");
     return (x & (x - 1)) == 0 && (x != 0);
 }
 
 inline int log2(int x)
 {
     int r = 0;
-    while ((x >> r) > 1) r++;
+    while ((x >> r) > 1)
+        r++;
     return r;
 }
 
 inline unsigned int ceilPow2(unsigned int x)
 {
-    if (x != 0) x--;
+    if (x != 0)
+        x--;
     x |= x >> 1;
     x |= x >> 2;
     x |= x >> 4;
     x |= x >> 8;
     x |= x >> 16;
     x++;
 
     return x;
@@ -103,29 +105,29 @@ inline unsigned int clampCast(bool value
 }
 
 template <>
 inline int clampCast(bool value)
 {
     return static_cast<int>(value);
 }
 
-template<typename T, typename MIN, typename MAX>
+template <typename T, typename MIN, typename MAX>
 inline T clamp(T x, MIN min, MAX max)
 {
     // Since NaNs fail all comparison tests, a NaN value will default to min
     return x > min ? (x > max ? max : x) : min;
 }
 
 inline float clamp01(float x)
 {
     return clamp(x, 0.0f, 1.0f);
 }
 
-template<const int n>
+template <const int n>
 inline unsigned int unorm(float x)
 {
     const unsigned int max = 0xFFFFFFFF >> (32 - n);
 
     if (x > 1)
     {
         return max;
     }
@@ -137,17 +139,17 @@ inline unsigned int unorm(float x)
     {
         return (unsigned int)(max * x + 0.5f);
     }
 }
 
 inline bool supportsSSE2()
 {
 #if defined(ANGLE_USE_SSE)
-    static bool checked = false;
+    static bool checked  = false;
     static bool supports = false;
 
     if (checked)
     {
         return supports;
     }
 
 #if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM)
@@ -177,79 +179,82 @@ destType bitCast(const sourceType &sourc
     destType output;
     memcpy(&output, &source, copySize);
     return output;
 }
 
 inline unsigned short float32ToFloat16(float fp32)
 {
     unsigned int fp32i = bitCast<unsigned int>(fp32);
-    unsigned int sign = (fp32i & 0x80000000) >> 16;
-    unsigned int abs = fp32i & 0x7FFFFFFF;
+    unsigned int sign  = (fp32i & 0x80000000) >> 16;
+    unsigned int abs   = fp32i & 0x7FFFFFFF;
 
-    if(abs > 0x47FFEFFF)   // Infinity
+    if (abs > 0x47FFEFFF)  // Infinity
     {
         return static_cast<unsigned short>(sign | 0x7FFF);
     }
-    else if(abs < 0x38800000)   // Denormal
+    else if (abs < 0x38800000)  // Denormal
     {
         unsigned int mantissa = (abs & 0x007FFFFF) | 0x00800000;
-        int e = 113 - (abs >> 23);
+        int e                 = 113 - (abs >> 23);
 
-        if(e < 24)
+        if (e < 24)
         {
             abs = mantissa >> e;
         }
         else
         {
             abs = 0;
         }
 
         return static_cast<unsigned short>(sign | (abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
     }
     else
     {
-        return static_cast<unsigned short>(sign | (abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
+        return static_cast<unsigned short>(
+            sign | (abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
     }
 }
 
 float float16ToFloat32(unsigned short h);
 
 unsigned int convertRGBFloatsTo999E5(float red, float green, float blue);
 void convert999E5toRGBFloats(unsigned int input, float *red, float *green, float *blue);
 
 inline unsigned short float32ToFloat11(float fp32)
 {
-    const unsigned int float32MantissaMask = 0x7FFFFF;
-    const unsigned int float32ExponentMask = 0x7F800000;
-    const unsigned int float32SignMask = 0x80000000;
-    const unsigned int float32ValueMask = ~float32SignMask;
+    const unsigned int float32MantissaMask     = 0x7FFFFF;
+    const unsigned int float32ExponentMask     = 0x7F800000;
+    const unsigned int float32SignMask         = 0x80000000;
+    const unsigned int float32ValueMask        = ~float32SignMask;
     const unsigned int float32ExponentFirstBit = 23;
-    const unsigned int float32ExponentBias = 127;
+    const unsigned int float32ExponentBias     = 127;
 
-    const unsigned short float11Max = 0x7BF;
+    const unsigned short float11Max          = 0x7BF;
     const unsigned short float11MantissaMask = 0x3F;
     const unsigned short float11ExponentMask = 0x7C0;
-    const unsigned short float11BitMask = 0x7FF;
-    const unsigned int float11ExponentBias = 14;
+    const unsigned short float11BitMask      = 0x7FF;
+    const unsigned int float11ExponentBias   = 14;
 
     const unsigned int float32Maxfloat11 = 0x477E0000;
     const unsigned int float32Minfloat11 = 0x38800000;
 
     const unsigned int float32Bits = bitCast<unsigned int>(fp32);
-    const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask;
+    const bool float32Sign         = (float32Bits & float32SignMask) == float32SignMask;
 
     unsigned int float32Val = float32Bits & float32ValueMask;
 
     if ((float32Val & float32ExponentMask) == float32ExponentMask)
     {
         // INF or NAN
         if ((float32Val & float32MantissaMask) != 0)
         {
-            return float11ExponentMask | (((float32Val >> 17) | (float32Val >> 11) | (float32Val >> 6) | (float32Val)) & float11MantissaMask);
+            return float11ExponentMask |
+                   (((float32Val >> 17) | (float32Val >> 11) | (float32Val >> 6) | (float32Val)) &
+                    float11MantissaMask);
         }
         else if (float32Sign)
         {
             // -INF is clamped to 0 since float11 is positive only
             return 0;
         }
         else
         {
@@ -267,58 +272,62 @@ inline unsigned short float32ToFloat11(f
         return float11Max;
     }
     else
     {
         if (float32Val < float32Minfloat11)
         {
             // The number is too small to be represented as a normalized float11
             // Convert it to a denormalized value.
-            const unsigned int shift = (float32ExponentBias - float11ExponentBias) - (float32Val >> float32ExponentFirstBit);
-            float32Val = ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
+            const unsigned int shift = (float32ExponentBias - float11ExponentBias) -
+                                       (float32Val >> float32ExponentFirstBit);
+            float32Val =
+                ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
         }
         else
         {
             // Rebias the exponent to represent the value as a normalized float11
             float32Val += 0xC8000000;
         }
 
         return ((float32Val + 0xFFFF + ((float32Val >> 17) & 1)) >> 17) & float11BitMask;
     }
 }
 
 inline unsigned short float32ToFloat10(float fp32)
 {
-    const unsigned int float32MantissaMask = 0x7FFFFF;
-    const unsigned int float32ExponentMask = 0x7F800000;
-    const unsigned int float32SignMask = 0x80000000;
-    const unsigned int float32ValueMask = ~float32SignMask;
+    const unsigned int float32MantissaMask     = 0x7FFFFF;
+    const unsigned int float32ExponentMask     = 0x7F800000;
+    const unsigned int float32SignMask         = 0x80000000;
+    const unsigned int float32ValueMask        = ~float32SignMask;
     const unsigned int float32ExponentFirstBit = 23;
-    const unsigned int float32ExponentBias = 127;
+    const unsigned int float32ExponentBias     = 127;
 
-    const unsigned short float10Max = 0x3DF;
+    const unsigned short float10Max          = 0x3DF;
     const unsigned short float10MantissaMask = 0x1F;
     const unsigned short float10ExponentMask = 0x3E0;
-    const unsigned short float10BitMask = 0x3FF;
-    const unsigned int float10ExponentBias = 14;
+    const unsigned short float10BitMask      = 0x3FF;
+    const unsigned int float10ExponentBias   = 14;
 
     const unsigned int float32Maxfloat10 = 0x477C0000;
     const unsigned int float32Minfloat10 = 0x38800000;
 
     const unsigned int float32Bits = bitCast<unsigned int>(fp32);
-    const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask;
+    const bool float32Sign         = (float32Bits & float32SignMask) == float32SignMask;
 
     unsigned int float32Val = float32Bits & float32ValueMask;
 
     if ((float32Val & float32ExponentMask) == float32ExponentMask)
     {
         // INF or NAN
         if ((float32Val & float32MantissaMask) != 0)
         {
-            return float10ExponentMask | (((float32Val >> 18) | (float32Val >> 13) | (float32Val >> 3) | (float32Val)) & float10MantissaMask);
+            return float10ExponentMask |
+                   (((float32Val >> 18) | (float32Val >> 13) | (float32Val >> 3) | (float32Val)) &
+                    float10MantissaMask);
         }
         else if (float32Sign)
         {
             // -INF is clamped to 0 since float11 is positive only
             return 0;
         }
         else
         {
@@ -336,18 +345,20 @@ inline unsigned short float32ToFloat10(f
         return float10Max;
     }
     else
     {
         if (float32Val < float32Minfloat10)
         {
             // The number is too small to be represented as a normalized float11
             // Convert it to a denormalized value.
-            const unsigned int shift = (float32ExponentBias - float10ExponentBias) - (float32Val >> float32ExponentFirstBit);
-            float32Val = ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
+            const unsigned int shift = (float32ExponentBias - float10ExponentBias) -
+                                       (float32Val >> float32ExponentFirstBit);
+            float32Val =
+                ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
         }
         else
         {
             // Rebias the exponent to represent the value as a normalized float11
             float32Val += 0xC8000000;
         }
 
         return ((float32Val + 0x1FFFF + ((float32Val >> 18) & 1)) >> 18) & float10BitMask;
@@ -374,22 +385,21 @@ inline float float11ToFloat32(unsigned s
         {
             // The value is denormalized
             exponent = 1;
 
             do
             {
                 exponent--;
                 mantissa <<= 1;
-            }
-            while ((mantissa & 0x40) == 0);
+            } while ((mantissa & 0x40) == 0);
 
             mantissa = mantissa & 0x3F;
         }
-        else // The value is zero
+        else  // The value is zero
         {
             exponent = static_cast<unsigned short>(-112);
         }
 
         return bitCast<float>(((exponent + 112) << 23) | (mantissa << 17));
     }
 }
 
@@ -413,30 +423,55 @@ inline float float10ToFloat32(unsigned s
         {
             // The value is denormalized
             exponent = 1;
 
             do
             {
                 exponent--;
                 mantissa <<= 1;
-            }
-            while ((mantissa & 0x20) == 0);
+            } while ((mantissa & 0x20) == 0);
 
             mantissa = mantissa & 0x1F;
         }
-        else // The value is zero
+        else  // The value is zero
         {
             exponent = static_cast<unsigned short>(-112);
         }
 
         return bitCast<float>(((exponent + 112) << 23) | (mantissa << 18));
     }
 }
 
+// Convers to and from float and 16.16 fixed point format.
+
+inline float FixedToFloat(uint32_t fixedInput)
+{
+    return static_cast<float>(fixedInput) / 65536.0f;
+}
+
+inline uint32_t FloatToFixed(float floatInput)
+{
+    static constexpr uint32_t kHighest = 32767 * 65536 + 65535;
+    static constexpr uint32_t kLowest  = static_cast<uint32_t>(-32768 * 65536 + 65535);
+
+    if (floatInput > 32767.65535)
+    {
+        return kHighest;
+    }
+    else if (floatInput < -32768.65535)
+    {
+        return kLowest;
+    }
+    else
+    {
+        return static_cast<uint32_t>(floatInput * 65536);
+    }
+}
+
 template <typename T>
 inline float normalizedToFloat(T input)
 {
     static_assert(std::numeric_limits<T>::is_integer, "T must be an integer.");
 
     const float inverseMax = 1.0f / std::numeric_limits<T>::max();
     return input * inverseMax;
 }
@@ -558,22 +593,26 @@ inline float average(float a, float b)
 
 inline unsigned short averageHalfFloat(unsigned short a, unsigned short b)
 {
     return float32ToFloat16((float16ToFloat32(a) + float16ToFloat32(b)) * 0.5f);
 }
 
 inline unsigned int averageFloat11(unsigned int a, unsigned int b)
 {
-    return float32ToFloat11((float11ToFloat32(static_cast<unsigned short>(a)) + float11ToFloat32(static_cast<unsigned short>(b))) * 0.5f);
+    return float32ToFloat11((float11ToFloat32(static_cast<unsigned short>(a)) +
+                             float11ToFloat32(static_cast<unsigned short>(b))) *
+                            0.5f);
 }
 
 inline unsigned int averageFloat10(unsigned int a, unsigned int b)
 {
-    return float32ToFloat10((float10ToFloat32(static_cast<unsigned short>(a)) + float10ToFloat32(static_cast<unsigned short>(b))) * 0.5f);
+    return float32ToFloat10((float10ToFloat32(static_cast<unsigned short>(a)) +
+                             float10ToFloat32(static_cast<unsigned short>(b))) *
+                            0.5f);
 }
 
 template <typename T>
 class Range
 {
   public:
     Range() {}
     Range(T lo, T hi) : mLow(lo), mHigh(hi) {}
@@ -682,60 +721,60 @@ inline float Ldexp(float x, int exp)
 // Then, the results are packed into the returned 32-bit unsigned integer.
 // The first float value will be written to the least significant bits of the output;
 // the last float value will be written to the most significant bits.
 // The conversion of each value to fixed point is done as follows :
 // packSnorm2x16 : round(clamp(c, -1, +1) * 32767.0)
 inline uint32_t packSnorm2x16(float f1, float f2)
 {
     int16_t leastSignificantBits = static_cast<int16_t>(roundf(clamp(f1, -1.0f, 1.0f) * 32767.0f));
-    int16_t mostSignificantBits = static_cast<int16_t>(roundf(clamp(f2, -1.0f, 1.0f) * 32767.0f));
+    int16_t mostSignificantBits  = static_cast<int16_t>(roundf(clamp(f2, -1.0f, 1.0f) * 32767.0f));
     return static_cast<uint32_t>(mostSignificantBits) << 16 |
            (static_cast<uint32_t>(leastSignificantBits) & 0xFFFF);
 }
 
-// First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then, each
-// component is converted to a normalized floating-point value to generate the returned two float values.
-// The first float value will be extracted from the least significant bits of the input;
-// the last float value will be extracted from the most-significant bits.
-// The conversion for unpacked fixed-point value to floating point is done as follows:
-// unpackSnorm2x16 : clamp(f / 32767.0, -1, +1)
+// First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then,
+// each component is converted to a normalized floating-point value to generate the returned two
+// float values. The first float value will be extracted from the least significant bits of the
+// input; the last float value will be extracted from the most-significant bits. The conversion for
+// unpacked fixed-point value to floating point is done as follows: unpackSnorm2x16 : clamp(f /
+// 32767.0, -1, +1)
 inline void unpackSnorm2x16(uint32_t u, float *f1, float *f2)
 {
     int16_t leastSignificantBits = static_cast<int16_t>(u & 0xFFFF);
-    int16_t mostSignificantBits = static_cast<int16_t>(u >> 16);
+    int16_t mostSignificantBits  = static_cast<int16_t>(u >> 16);
     *f1 = clamp(static_cast<float>(leastSignificantBits) / 32767.0f, -1.0f, 1.0f);
     *f2 = clamp(static_cast<float>(mostSignificantBits) / 32767.0f, -1.0f, 1.0f);
 }
 
 // First, both normalized floating-point values are converted into 16-bit integer values.
 // Then, the results are packed into the returned 32-bit unsigned integer.
 // The first float value will be written to the least significant bits of the output;
 // the last float value will be written to the most significant bits.
 // The conversion of each value to fixed point is done as follows:
 // packUnorm2x16 : round(clamp(c, 0, +1) * 65535.0)
 inline uint32_t packUnorm2x16(float f1, float f2)
 {
     uint16_t leastSignificantBits = static_cast<uint16_t>(roundf(clamp(f1, 0.0f, 1.0f) * 65535.0f));
-    uint16_t mostSignificantBits = static_cast<uint16_t>(roundf(clamp(f2, 0.0f, 1.0f) * 65535.0f));
-    return static_cast<uint32_t>(mostSignificantBits) << 16 | static_cast<uint32_t>(leastSignificantBits);
+    uint16_t mostSignificantBits  = static_cast<uint16_t>(roundf(clamp(f2, 0.0f, 1.0f) * 65535.0f));
+    return static_cast<uint32_t>(mostSignificantBits) << 16 |
+           static_cast<uint32_t>(leastSignificantBits);
 }
 
-// First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then, each
-// component is converted to a normalized floating-point value to generate the returned two float values.
-// The first float value will be extracted from the least significant bits of the input;
-// the last float value will be extracted from the most-significant bits.
-// The conversion for unpacked fixed-point value to floating point is done as follows:
-// unpackUnorm2x16 : f / 65535.0
+// First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then,
+// each component is converted to a normalized floating-point value to generate the returned two
+// float values. The first float value will be extracted from the least significant bits of the
+// input; the last float value will be extracted from the most-significant bits. The conversion for
+// unpacked fixed-point value to floating point is done as follows: unpackUnorm2x16 : f / 65535.0
 inline void unpackUnorm2x16(uint32_t u, float *f1, float *f2)
 {
     uint16_t leastSignificantBits = static_cast<uint16_t>(u & 0xFFFF);
-    uint16_t mostSignificantBits = static_cast<uint16_t>(u >> 16);
-    *f1 = static_cast<float>(leastSignificantBits) / 65535.0f;
-    *f2 = static_cast<float>(mostSignificantBits) / 65535.0f;
+    uint16_t mostSignificantBits  = static_cast<uint16_t>(u >> 16);
+    *f1                           = static_cast<float>(leastSignificantBits) / 65535.0f;
+    *f2                           = static_cast<float>(mostSignificantBits) / 65535.0f;
 }
 
 // Helper functions intended to be used only here.
 namespace priv
 {
 
 inline uint8_t ToPackedUnorm8(float f)
 {
@@ -816,29 +855,30 @@ inline void UnpackSnorm4x8(uint32_t u, f
 // Returns an unsigned integer obtained by converting the two floating-point values to the 16-bit
 // floating-point representation found in the OpenGL ES Specification, and then packing these
 // two 16-bit integers into a 32-bit unsigned integer.
 // f1: The 16 least-significant bits of the result;
 // f2: The 16 most-significant bits.
 inline uint32_t packHalf2x16(float f1, float f2)
 {
     uint16_t leastSignificantBits = static_cast<uint16_t>(float32ToFloat16(f1));
-    uint16_t mostSignificantBits = static_cast<uint16_t>(float32ToFloat16(f2));
-    return static_cast<uint32_t>(mostSignificantBits) << 16 | static_cast<uint32_t>(leastSignificantBits);
+    uint16_t mostSignificantBits  = static_cast<uint16_t>(float32ToFloat16(f2));
+    return static_cast<uint32_t>(mostSignificantBits) << 16 |
+           static_cast<uint32_t>(leastSignificantBits);
 }
 
-// Returns two floating-point values obtained by unpacking a 32-bit unsigned integer into a pair of 16-bit values,
-// interpreting those values as 16-bit floating-point numbers according to the OpenGL ES Specification,
-// and converting them to 32-bit floating-point values.
-// The first float value is obtained from the 16 least-significant bits of u;
-// the second component is obtained from the 16 most-significant bits of u.
+// Returns two floating-point values obtained by unpacking a 32-bit unsigned integer into a pair of
+// 16-bit values, interpreting those values as 16-bit floating-point numbers according to the OpenGL
+// ES Specification, and converting them to 32-bit floating-point values. The first float value is
+// obtained from the 16 least-significant bits of u; the second component is obtained from the 16
+// most-significant bits of u.
 inline void unpackHalf2x16(uint32_t u, float *f1, float *f2)
 {
     uint16_t leastSignificantBits = static_cast<uint16_t>(u & 0xFFFF);
-    uint16_t mostSignificantBits = static_cast<uint16_t>(u >> 16);
+    uint16_t mostSignificantBits  = static_cast<uint16_t>(u >> 16);
 
     *f1 = float16ToFloat32(leastSignificantBits);
     *f2 = float16ToFloat32(mostSignificantBits);
 }
 
 inline uint8_t sRGBToLinear(uint8_t srgbValue)
 {
     float value = srgbValue / 255.0f;
@@ -999,31 +1039,35 @@ int FindMSB(T bits)
     }
     else
     {
         return static_cast<int>(ScanReverse(bits));
     }
 }
 
 // Returns whether the argument is Not a Number.
-// IEEE 754 single precision NaN representation: Exponent(8 bits) - 255, Mantissa(23 bits) - non-zero.
+// IEEE 754 single precision NaN representation: Exponent(8 bits) - 255, Mantissa(23 bits) -
+// non-zero.
 inline bool isNaN(float f)
 {
     // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u
     // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu
-    return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) && (bitCast<uint32_t>(f) & 0x7fffffu);
+    return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) &&
+           (bitCast<uint32_t>(f) & 0x7fffffu);
 }
 
 // Returns whether the argument is infinity.
-// IEEE 754 single precision infinity representation: Exponent(8 bits) - 255, Mantissa(23 bits) - zero.
+// IEEE 754 single precision infinity representation: Exponent(8 bits) - 255, Mantissa(23 bits) -
+// zero.
 inline bool isInf(float f)
 {
     // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u
     // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu
-    return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) && !(bitCast<uint32_t>(f) & 0x7fffffu);
+    return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) &&
+           !(bitCast<uint32_t>(f) & 0x7fffffu);
 }
 
 namespace priv
 {
 template <unsigned int N, unsigned int R>
 struct iSquareRoot
 {
     static constexpr unsigned int solve()
@@ -1112,31 +1156,30 @@ angle::CheckedNumeric<T> CheckedRoundUp(
 inline unsigned int UnsignedCeilDivide(unsigned int value, unsigned int divisor)
 {
     unsigned int divided = value / divisor;
     return (divided + ((value % divisor == 0) ? 0 : 1));
 }
 
 #if defined(_MSC_VER)
 
-#define ANGLE_ROTL(x,y) _rotl(x,y)
-#define ANGLE_ROTR16(x,y) _rotr16(x,y)
+#define ANGLE_ROTL(x, y) _rotl(x, y)
+#define ANGLE_ROTR16(x, y) _rotr16(x, y)
 
 #else
 
 inline uint32_t RotL(uint32_t x, int8_t r)
 {
     return (x << r) | (x >> (32 - r));
 }
 
 inline uint16_t RotR16(uint16_t x, int8_t r)
 {
     return (x >> r) | (x << (16 - r));
 }
 
 #define ANGLE_ROTL(x, y) ::rx::RotL(x, y)
 #define ANGLE_ROTR16(x, y) ::rx::RotR16(x, y)
 
-#endif // namespace rx
-
+#endif  // namespace rx
 }
 
-#endif   // COMMON_MATHUTIL_H_
+#endif  // COMMON_MATHUTIL_H_
--- a/gfx/angle/checkout/src/common/matrix_utils.h
+++ b/gfx/angle/checkout/src/common/matrix_utils.h
@@ -89,16 +89,38 @@ class Matrix
     {
         ASSERT(columns() == m.rows());
         Matrix<T> res  = (*this) * m;
         size_t numElts = res.elements().size();
         mElements.resize(numElts);
         memcpy(mElements.data(), res.data(), numElts * sizeof(float));
     }
 
+    bool operator==(const Matrix<T> &m) const
+    {
+        ASSERT(columns() == m.columns());
+        ASSERT(rows() == m.rows());
+        return mElements == m.elements();
+    }
+
+    bool operator!=(const Matrix<T> &m) const { return !(mElements == m.elements()); }
+
+    bool nearlyEqual(T epsilon, const Matrix<T> &m) const
+    {
+        ASSERT(columns() == m.columns());
+        ASSERT(rows() == m.rows());
+        const auto &otherElts = m.elements();
+        for (size_t i = 0; i < otherElts.size(); i++)
+        {
+            if ((mElements[i] - otherElts[i] > epsilon) && (otherElts[i] - mElements[i] > epsilon))
+                return false;
+        }
+        return true;
+    }
+
     unsigned int size() const
     {
         ASSERT(rows() == columns());
         return rows();
     }
 
     unsigned int rows() const { return mRows; }
 
--- a/gfx/angle/checkout/src/common/utilities.cpp
+++ b/gfx/angle/checkout/src/common/utilities.cpp
@@ -432,60 +432,16 @@ bool IsAtomicCounterType(GLenum type)
 }
 
 bool IsOpaqueType(GLenum type)
 {
     // ESSL 3.10 section 4.1.7 defines opaque types as: samplers, images and atomic counters.
     return IsImageType(type) || IsSamplerType(type) || IsAtomicCounterType(type);
 }
 
-GLenum SamplerTypeToTextureType(GLenum samplerType)
-{
-    switch (samplerType)
-    {
-      case GL_SAMPLER_2D:
-      case GL_INT_SAMPLER_2D:
-      case GL_UNSIGNED_INT_SAMPLER_2D:
-      case GL_SAMPLER_2D_SHADOW:
-        return GL_TEXTURE_2D;
-
-      case GL_SAMPLER_EXTERNAL_OES:
-          return GL_TEXTURE_EXTERNAL_OES;
-
-      case GL_SAMPLER_CUBE:
-      case GL_INT_SAMPLER_CUBE:
-      case GL_UNSIGNED_INT_SAMPLER_CUBE:
-      case GL_SAMPLER_CUBE_SHADOW:
-        return GL_TEXTURE_CUBE_MAP;
-
-      case GL_SAMPLER_2D_ARRAY:
-      case GL_INT_SAMPLER_2D_ARRAY:
-      case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
-      case GL_SAMPLER_2D_ARRAY_SHADOW:
-        return GL_TEXTURE_2D_ARRAY;
-
-      case GL_SAMPLER_3D:
-      case GL_INT_SAMPLER_3D:
-      case GL_UNSIGNED_INT_SAMPLER_3D:
-        return GL_TEXTURE_3D;
-
-      case GL_SAMPLER_2D_MULTISAMPLE:
-      case GL_INT_SAMPLER_2D_MULTISAMPLE:
-      case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
-          return GL_TEXTURE_2D_MULTISAMPLE;
-
-      case GL_SAMPLER_2D_RECT_ANGLE:
-          return GL_TEXTURE_RECTANGLE_ANGLE;
-
-      default:
-        UNREACHABLE();
-        return 0;
-    }
-}
-
 bool IsMatrixType(GLenum type)
 {
     return VariableRowCount(type) > 1;
 }
 
 GLenum TransposeMatrixType(GLenum type)
 {
     if (!IsMatrixType(type))
@@ -540,39 +496,16 @@ int AllocateFirstFreeBits(unsigned int *
         }
 
         mask <<= 1;
     }
 
     return -1;
 }
 
-static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1, "Unexpected GL cube map enum value.");
-static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2, "Unexpected GL cube map enum value.");
-static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3, "Unexpected GL cube map enum value.");
-static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4, "Unexpected GL cube map enum value.");
-static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5, "Unexpected GL cube map enum value.");
-
-bool IsCubeMapTextureTarget(GLenum target)
-{
-    return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
-}
-
-size_t CubeMapTextureTargetToLayerIndex(GLenum target)
-{
-    ASSERT(IsCubeMapTextureTarget(target));
-    return target - static_cast<size_t>(FirstCubeMapTextureTarget);
-}
-
-GLenum LayerIndexToCubeMapTextureTarget(size_t index)
-{
-    ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
-    return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
-}
-
 IndexRange ComputeIndexRange(GLenum indexType,
                              const GLvoid *indices,
                              size_t count,
                              bool primitiveRestartEnabled)
 {
     switch (indexType)
     {
         case GL_UNSIGNED_BYTE:
@@ -991,62 +924,16 @@ const char *GetGenericErrorMessage(EGLin
             return "Unknown error.";
     }
 }
 
 }  // namespace egl
 
 namespace egl_gl
 {
-GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget)
-{
-    ASSERT(egl::IsCubeMapTextureTarget(eglTarget));
-    return gl::LayerIndexToCubeMapTextureTarget(egl::CubeMapTextureTargetToLayerIndex(eglTarget));
-}
-
-GLenum EGLImageTargetToGLTextureTarget(EGLenum eglTarget)
-{
-    switch (eglTarget)
-    {
-        case EGL_GL_TEXTURE_2D_KHR:
-            return GL_TEXTURE_2D;
-
-        case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
-        case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
-        case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
-        case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
-        case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
-        case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
-            return EGLCubeMapTargetToGLCubeMapTarget(eglTarget);
-
-        case EGL_GL_TEXTURE_3D_KHR:
-            return GL_TEXTURE_3D;
-
-        default:
-            UNREACHABLE();
-            return GL_NONE;
-    }
-}
-
-GLenum EGLTextureTargetToGLTextureTarget(EGLenum eglTarget)
-{
-    switch (eglTarget)
-    {
-        case EGL_TEXTURE_2D:
-            return GL_TEXTURE_2D;
-
-        case EGL_TEXTURE_RECTANGLE_ANGLE:
-            return GL_TEXTURE_RECTANGLE_ANGLE;
-
-        default:
-            UNREACHABLE();
-            return GL_NONE;
-    }
-}
-
 GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
 {
     return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
 }
 }  // namespace egl_gl
 
 namespace gl_egl
 {
--- a/gfx/angle/checkout/src/common/utilities.h
+++ b/gfx/angle/checkout/src/common/utilities.h
@@ -33,33 +33,26 @@ size_t VariableComponentSize(GLenum type
 size_t VariableInternalSize(GLenum type);
 size_t VariableExternalSize(GLenum type);
 int VariableRowCount(GLenum type);
 int VariableColumnCount(GLenum type);
 bool IsSamplerType(GLenum type);
 bool IsImageType(GLenum type);
 bool IsAtomicCounterType(GLenum type);
 bool IsOpaqueType(GLenum type);
-GLenum SamplerTypeToTextureType(GLenum samplerType);
 bool IsMatrixType(GLenum type);
 GLenum TransposeMatrixType(GLenum type);
 int VariableRegisterCount(GLenum type);
 int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix);
 int MatrixComponentCount(GLenum type, bool isRowMajorMatrix);
 int VariableSortOrder(GLenum type);
 GLenum VariableBoolVectorType(GLenum type);
 
 int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
 
-static const GLenum FirstCubeMapTextureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
-static const GLenum LastCubeMapTextureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
-bool IsCubeMapTextureTarget(GLenum target);
-size_t CubeMapTextureTargetToLayerIndex(GLenum target);
-GLenum LayerIndexToCubeMapTextureTarget(size_t index);
-
 // Parse the base resource name and array indices. Returns the base name of the resource.
 // If the provided name doesn't index an array, the outSubscripts vector will be empty.
 // If the provided name indexes an array, the outSubscripts vector will contain indices with
 // outermost array indices in the back. If an array index is invalid, GL_INVALID_INDEX is added to
 // outSubscripts.
 std::string ParseResourceName(const std::string &name, std::vector<unsigned int> *outSubscripts);
 
 // Find the child field which matches 'fullName' == var.name + "." + field.name.
@@ -156,19 +149,16 @@ EGLenum LayerIndexToCubeMapTextureTarget
 bool IsTextureTarget(EGLenum target);
 bool IsRenderbufferTarget(EGLenum target);
 
 const char *GetGenericErrorMessage(EGLint error);
 }  // namespace egl
 
 namespace egl_gl
 {
-GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget);
-GLenum EGLImageTargetToGLTextureTarget(EGLenum eglTarget);
-GLenum EGLTextureTargetToGLTextureTarget(EGLenum eglTarget);
 GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer);
 }
 
 namespace gl_egl
 {
 EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType);
 }  // namespace gl_egl
 
--- a/gfx/angle/checkout/src/compiler/preprocessor/Tokenizer.cpp
+++ b/gfx/angle/checkout/src/compiler/preprocessor/Tokenizer.cpp
@@ -932,16 +932,17 @@ typedef pp::SourceLocation YYLTYPE;
 #define YY_USER_INIT                   \
     do {                               \
         yyfileno = 0;                  \
         yylineno = 1;                  \
         yyextra->leadingSpace = false; \
         yyextra->lineStart = true;     \
     } while(0);
 
+#define YY_NO_INPUT
 #define YY_USER_ACTION                                              \
     do                                                              \
     {                                                               \
         pp::Input* input = &yyextra->input;                         \
         pp::Input::Location* scanLoc = &yyextra->scanLoc;           \
         while ((scanLoc->sIndex < input->count()) &&                \
                (scanLoc->cIndex >= input->length(scanLoc->sIndex))) \
         {                                                           \
--- a/gfx/angle/checkout/src/compiler/preprocessor/Tokenizer.l
+++ b/gfx/angle/checkout/src/compiler/preprocessor/Tokenizer.l
@@ -59,16 +59,17 @@ typedef pp::SourceLocation YYLTYPE;
 #define YY_USER_INIT                   \
     do {                               \
         yyfileno = 0;                  \
         yylineno = 1;                  \
         yyextra->leadingSpace = false; \
         yyextra->lineStart = true;     \
     } while(0);
 
+#define YY_NO_INPUT
 #define YY_USER_ACTION                                              \
     do                                                              \
     {                                                               \
         pp::Input* input = &yyextra->input;                         \
         pp::Input::Location* scanLoc = &yyextra->scanLoc;           \
         while ((scanLoc->sIndex < input->count()) &&                \
                (scanLoc->cIndex >= input->length(scanLoc->sIndex))) \
         {                                                           \
--- a/gfx/angle/checkout/src/compiler/preprocessor/numeric_lex.h
+++ b/gfx/angle/checkout/src/compiler/preprocessor/numeric_lex.h
@@ -43,30 +43,17 @@ bool numeric_lex_int(const std::string &
 
     stream >> (*value);
     return !stream.fail();
 }
 
 template <typename FloatType>
 bool numeric_lex_float(const std::string &str, FloatType *value)
 {
-// On 64-bit Intel Android, istringstream is broken.  Until this is fixed in
-// a newer NDK, don't use it.  Android doesn't have locale support, so this
-// doesn't have to force the C locale.
-// TODO(thakis): Remove this once this bug has been fixed in the NDK and
-// that NDK has been rolled into chromium.
-#if defined(ANGLE_PLATFORM_ANDROID) && __x86_64__
-    *value = strtod(str.c_str(), nullptr);
-    return errno != ERANGE;
-#else
-    std::istringstream stream(str);
-    // Force "C" locale so that decimal character is always '.', and
-    // not dependent on the current locale.
-    stream.imbue(std::locale::classic());
-
-    stream >> (*value);
-    return !stream.fail() && std::isfinite(*value);
-#endif
+    // Some platforms have issues with the usage of std::locale and std::stringstream and cause
+    // crashes. Usage of strtod appears to be safe.
+    *value = static_cast<FloatType>(strtod(str.c_str(), nullptr));
+    return errno != ERANGE && std::isfinite(*value);
 }
 
 }  // namespace pp.
 
 #endif  // COMPILER_PREPROCESSOR_NUMERICLEX_H_
--- a/gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.cpp
@@ -4,18 +4,18 @@
 // 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/IntermTraverse.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
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/AddAndTrueToLoopCondition.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-//
-// Copyright (c) 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/AddAndTrueToLoopCondition.h"
-
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/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
-
-void AddAndTrueToLoopCondition(TIntermNode *root)
-{
-    AddAndTrueToLoopConditionTraverser traverser;
-    root->traverse(&traverser);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/AddAndTrueToLoopCondition.h
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-// Copyright (c) 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_ADDANDTRUETOLOOPCONDITION_H_
-#define COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_
-
-class TIntermNode;
-namespace sh
-{
-
-void AddAndTrueToLoopCondition(TIntermNode *root);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/AddDefaultReturnStatements.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-//
-// Copyright (c) 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/AddDefaultReturnStatements.h"
-
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/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
-
-void AddDefaultReturnStatements(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);
-        }
-    }
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/AddDefaultReturnStatements.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//
-// Copyright (c) 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_ADDDEFAULTRETURNSTATEMENTS_H_
-#define COMPILER_TRANSLATOR_ADDDEFAULTRETURNSTATEMENTS_H_
-
-class TIntermBlock;
-
-namespace sh
-{
-
-void AddDefaultReturnStatements(TIntermBlock *root);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_ADDDEFAULTRETURNSTATEMENTS_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// The ArrayReturnValueToOutParameter function changes return values of an array type to out
-// parameters in function definitions, prototypes, and call sites.
-
-#include "compiler/translator/ArrayReturnValueToOutParameter.h"
-
-#include <map>
-
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/StaticType.h"
-#include "compiler/translator/SymbolTable.h"
-
-namespace sh
-{
-
-namespace
-{
-
-constexpr const ImmutableString kReturnValueVariableName("angle_return");
-
-void CopyAggregateChildren(TIntermAggregateBase *from, TIntermAggregateBase *to)
-{
-    const TIntermSequence *fromSequence = from->getSequence();
-    for (size_t ii = 0; ii < fromSequence->size(); ++ii)
-    {
-        to->getSequence()->push_back(fromSequence->at(ii));
-    }
-}
-
-class ArrayReturnValueToOutParameterTraverser : private TIntermTraverser
-{
-  public:
-    static void apply(TIntermNode *root, TSymbolTable *symbolTable);
-
-  private:
-    ArrayReturnValueToOutParameterTraverser(TSymbolTable *symbolTable);
-
-    bool visitFunctionPrototype(Visit visit, 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 = new TIntermSequence();
-    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;
-}
-
-void ArrayReturnValueToOutParameterTraverser::apply(TIntermNode *root, TSymbolTable *symbolTable)
-{
-    ArrayReturnValueToOutParameterTraverser arrayReturnValueToOutParam(symbolTable);
-    root->traverse(&arrayReturnValueToOutParam);
-    arrayReturnValueToOutParam.updateTree();
-}
-
-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;
-}
-
-bool ArrayReturnValueToOutParameterTraverser::visitFunctionPrototype(Visit visit,
-                                                                     TIntermFunctionPrototype *node)
-{
-    if (visit == PreVisit && 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(EvqOut);
-            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>(), false);
-            for (size_t i = 0; i < node->getFunction()->getParamCount(); ++i)
-            {
-                func->addParameter(node->getFunction()->getParam(i));
-            }
-            func->addParameter(TConstParameter(
-                kReturnValueVariableName, static_cast<const TType *>(returnValueVariableType)));
-            changedFunction.func                = func;
-            mChangedFunctions[functionId.get()] = changedFunction;
-        }
-        TIntermFunctionPrototype *replacement =
-            new TIntermFunctionPrototype(mChangedFunctions[functionId.get()].func);
-        CopyAggregateChildren(node, replacement);
-        replacement->getSequence()->push_back(
-            new TIntermSymbol(mChangedFunctions[functionId.get()].returnValueVariable));
-        replacement->setLine(node->getLine());
-
-        queueReplacement(replacement, OriginalNode::IS_DROPPED);
-    }
-    return false;
-}
-
-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.push_back(
-                NodeReplaceWithMultipleEntry(parentBlock, node, 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.push_back(
-            NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(), node, 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
-
-void ArrayReturnValueToOutParameter(TIntermNode *root, TSymbolTable *symbolTable)
-{
-    ArrayReturnValueToOutParameterTraverser::apply(root, symbolTable);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ArrayReturnValueToOutParameter.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// The ArrayReturnValueToOutParameter function changes return values of an array type to out
-// parameters in function definitions, prototypes and call sites.
-
-#ifndef COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
-#define COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
-
-namespace sh
-{
-
-class TIntermNode;
-class TSymbolTable;
-
-void ArrayReturnValueToOutParameter(TIntermNode *root, TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
--- a/gfx/angle/checkout/src/compiler/translator/BaseTypes.h
+++ b/gfx/angle/checkout/src/compiler/translator/BaseTypes.h
@@ -52,28 +52,22 @@ inline const char *getPrecisionString(TP
 //
 enum TBasicType
 {
     EbtVoid,
     EbtFloat,
     EbtInt,
     EbtUInt,
     EbtBool,
-    EbtGVec4,              // non type: represents vec4, ivec4, and uvec4
-    EbtGenType,            // non type: represents float, vec2, vec3, and vec4
-    EbtGenIType,           // non type: represents int, ivec2, ivec3, and ivec4
-    EbtGenUType,           // non type: represents uint, uvec2, uvec3, and uvec4
-    EbtGenBType,           // non type: represents bool, bvec2, bvec3, and bvec4
-    EbtVec,                // non type: represents vec2, vec3, and vec4
-    EbtIVec,               // non type: represents ivec2, ivec3, and ivec4
-    EbtUVec,               // non type: represents uvec2, uvec3, and uvec4
-    EbtBVec,               // non type: represents bvec2, bvec3, and bvec4
+
+    EbtAtomicCounter,
     EbtYuvCscStandardEXT,  // Only valid if EXT_YUV_target exists.
+
     EbtGuardSamplerBegin,  // non type: see implementation of IsSampler()
-    EbtSampler2D,
+    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,
     EbtISampler2D,
@@ -84,163 +78,67 @@ enum TBasicType
     EbtUSampler2D,
     EbtUSampler3D,
     EbtUSamplerCube,
     EbtUSampler2DArray,
     EbtUSampler2DMS,
     EbtSampler2DShadow,
     EbtSamplerCubeShadow,
     EbtSampler2DArrayShadow,
-    EbtGuardSamplerEnd,  // non type: see implementation of IsSampler()
-    EbtGSampler2D,       // non type: represents sampler2D, isampler2D, and usampler2D
-    EbtGSampler3D,       // non type: represents sampler3D, isampler3D, and usampler3D
-    EbtGSamplerCube,     // non type: represents samplerCube, isamplerCube, and usamplerCube
-    EbtGSampler2DArray,  // non type: represents sampler2DArray, isampler2DArray, and
-                         // usampler2DArray
-    EbtGSampler2DMS,     // non type: represents sampler2DMS, isampler2DMS, and usampler2DMS
+    EbtGuardSamplerEnd = EbtSampler2DArrayShadow,  // non type: see implementation of IsSampler()
 
     // images
     EbtGuardImageBegin,
-    EbtImage2D,
+    EbtImage2D = EbtGuardImageBegin,
     EbtIImage2D,
     EbtUImage2D,
     EbtImage3D,
     EbtIImage3D,
     EbtUImage3D,
     EbtImage2DArray,
     EbtIImage2DArray,
     EbtUImage2DArray,
     EbtImageCube,
     EbtIImageCube,
     EbtUImageCube,
-    EbtGuardImageEnd,
+    EbtGuardImageEnd = EbtUImageCube,
 
-    EbtGuardGImageBegin,
-    EbtGImage2D,       // non type: represents image2D, uimage2D, iimage2D
-    EbtGImage3D,       // non type: represents image3D, uimage3D, iimage3D
-    EbtGImage2DArray,  // non type: represents image2DArray, uimage2DArray, iimage2DArray
-    EbtGImageCube,     // non type: represents imageCube, uimageCube, iimageCube
-    EbtGuardGImageEnd,
+    EbtLastSimpleType = EbtGuardImageEnd,
 
     EbtStruct,
     EbtInterfaceBlock,
-    EbtAddress,  // should be deprecated??
-
-    EbtAtomicCounter,
 
     // end of list
-    EbtLast
+    EbtLast = EbtInterfaceBlock
 };
 
-constexpr const char *GetBasicMangledName(TBasicType t)
+constexpr char GetBasicMangledName(TBasicType t)
 {
-    switch (t)
+    if (t > EbtLastSimpleType)
     {
-        case EbtFloat:
-            return "f";
-        case EbtInt:
-            return "i";
-        case EbtUInt:
-            return "u";
-        case EbtBool:
-            return "b";
-        case EbtYuvCscStandardEXT:
-            return "ycs";
-        case EbtSampler2D:
-            return "s2";
-        case EbtSampler3D:
-            return "s3";
-        case EbtSamplerCube:
-            return "sC";
-        case EbtSampler2DArray:
-            return "s2a";
-        case EbtSamplerExternalOES:
-            return "sext";
-        case EbtSamplerExternal2DY2YEXT:
-            return "sext2y2y";
-        case EbtSampler2DRect:
-            return "s2r";
-        case EbtSampler2DMS:
-            return "s2ms";
-        case EbtISampler2D:
-            return "is2";
-        case EbtISampler3D:
-            return "is3";
-        case EbtISamplerCube:
-            return "isC";
-        case EbtISampler2DArray:
-            return "is2a";
-        case EbtISampler2DMS:
-            return "is2ms";
-        case EbtUSampler2D:
-            return "us2";
-        case EbtUSampler3D:
-            return "us3";
-        case EbtUSamplerCube:
-            return "usC";
-        case EbtUSampler2DArray:
-            return "us2a";
-        case EbtUSampler2DMS:
-            return "us2ms";
-        case EbtSampler2DShadow:
-            return "s2s";
-        case EbtSamplerCubeShadow:
-            return "sCs";
-        case EbtSampler2DArrayShadow:
-            return "s2as";
-        case EbtImage2D:
-            return "im2";
-        case EbtIImage2D:
-            return "iim2";
-        case EbtUImage2D:
-            return "uim2";
-        case EbtImage3D:
-            return "im3";
-        case EbtIImage3D:
-            return "iim3";
-        case EbtUImage3D:
-            return "uim3";
-        case EbtImage2DArray:
-            return "im2a";
-        case EbtIImage2DArray:
-            return "iim2a";
-        case EbtUImage2DArray:
-            return "uim2a";
-        case EbtImageCube:
-            return "imc";
-        case EbtIImageCube:
-            return "iimc";
-        case EbtUImageCube:
-            return "uimc";
-        case EbtAtomicCounter:
-            return "ac";
-        case EbtStruct:
-        case EbtInterfaceBlock:
-            return nullptr;
-        default:
-            // EbtVoid, EbtAddress and non types
-            return "";
+        return '{';
     }
+    static_assert(EbtLastSimpleType < 52, "We only use alphabetic characters for mangled names");
+    if (t < 26)
+    {
+        return static_cast<char>('A' + t);
+    }
+    return static_cast<char>('a' - 26 + t);
 }
 
 const char *getBasicString(TBasicType t);
 
 inline bool IsSampler(TBasicType type)
 {
-    return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
+    return type >= EbtGuardSamplerBegin && type <= EbtGuardSamplerEnd;
 }
 
 inline bool IsImage(TBasicType type)
 {
-    return type > EbtGuardImageBegin && type < EbtGuardImageEnd;
-}
-
-inline bool IsGImage(TBasicType type)
-{
-    return type > EbtGuardGImageBegin && type < EbtGuardGImageEnd;
+    return type >= EbtGuardImageBegin && type <= EbtGuardImageEnd;
 }
 
 inline bool IsAtomicCounter(TBasicType type)
 {
     return type == EbtAtomicCounter;
 }
 
 inline bool IsOpaqueType(TBasicType type)
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-//
-// Copyright (c) 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 "BreakVariableAliasingInInnerLoops.h"
-
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/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)
-    {
-        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)
-    {
-        if (visit == PreVisit)
-        {
-            mLoopLevel++;
-        }
-        else
-        {
-            ASSERT(mLoopLevel > 0);
-            mLoopLevel--;
-        }
-
-        return true;
-    }
-
-  private:
-    int mLoopLevel = 0;
-};
-
-}  // anonymous namespace
-
-void BreakVariableAliasingInInnerLoops(TIntermNode *root)
-{
-    AliasingBreaker breaker;
-    root->traverse(&breaker);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/BreakVariableAliasingInInnerLoops.h
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright (c) 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_BREAKVARIABLEALIASINGININNERLOOPS_H_
-#define COMPILER_TRANSLATOR_BREAKVARIABLEALIASINGININNERLOOPS_H_
-
-class TIntermNode;
-
-namespace sh
-{
-
-void BreakVariableAliasingInInnerLoops(TIntermNode *root);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_BREAKVARIABLEALIASINGININNERLOOPS_H_
--- a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.cpp
@@ -1,174 +1,77 @@
 //
 // Copyright (c) 2002-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.
 //
 
 #include "compiler/translator/BuiltInFunctionEmulator.h"
 #include "angle_gl.h"
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/SymbolTable.h"
 #include "compiler/translator/StaticType.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 (visit == PreVisit)
+        if (node->getFunction())
         {
-            bool needToEmulate =
-                mEmulator.setFunctionCalled(node->getOp(), node->getOperand()->getType());
+            bool needToEmulate = mEmulator.setFunctionCalled(node->getFunction());
             if (needToEmulate)
                 node->setUseEmulatedFunction();
         }
         return true;
     }
 
     bool visitAggregate(Visit visit, TIntermAggregate *node) override
     {
-        if (visit == PreVisit)
+        // Here we handle all the built-in functions mapped to ops, not just the ones that are
+        // currently identified as problematic.
+        if (node->isConstructor() || node->isFunctionCall())
         {
-            // Here we handle all the built-in functions mapped to ops, not just the ones that are
-            // currently identified as problematic.
-            if (node->isConstructor() || node->isFunctionCall())
-            {
-                return true;
-            }
-            const TIntermSequence &sequence = *(node->getSequence());
-            bool needToEmulate              = false;
-            // Right now we only handle built-in functions with two to four parameters.
-            if (sequence.size() == 2)
-            {
-                TIntermTyped *param1 = sequence[0]->getAsTyped();
-                TIntermTyped *param2 = sequence[1]->getAsTyped();
-                if (!param1 || !param2)
-                    return true;
-                needToEmulate = mEmulator.setFunctionCalled(node->getOp(), param1->getType(),
-                                                            param2->getType());
-            }
-            else if (sequence.size() == 3)
-            {
-                TIntermTyped *param1 = sequence[0]->getAsTyped();
-                TIntermTyped *param2 = sequence[1]->getAsTyped();
-                TIntermTyped *param3 = sequence[2]->getAsTyped();
-                if (!param1 || !param2 || !param3)
-                    return true;
-                needToEmulate = mEmulator.setFunctionCalled(node->getOp(), param1->getType(),
-                                                            param2->getType(), param3->getType());
-            }
-            else if (sequence.size() == 4)
-            {
-                TIntermTyped *param1 = sequence[0]->getAsTyped();
-                TIntermTyped *param2 = sequence[1]->getAsTyped();
-                TIntermTyped *param3 = sequence[2]->getAsTyped();
-                TIntermTyped *param4 = sequence[3]->getAsTyped();
-                if (!param1 || !param2 || !param3 || !param4)
-                    return true;
-                needToEmulate =
-                    mEmulator.setFunctionCalled(node->getOp(), param1->getType(), param2->getType(),
-                                                param3->getType(), param4->getType());
-            }
-            else
-            {
-                return true;
-            }
-
-            if (needToEmulate)
-                node->setUseEmulatedFunction();
+            return true;
         }
+        bool needToEmulate = mEmulator.setFunctionCalled(node->getFunction());
+        if (needToEmulate)
+            node->setUseEmulatedFunction();
         return true;
     }
 
   private:
     BuiltInFunctionEmulator &mEmulator;
 };
 
 BuiltInFunctionEmulator::BuiltInFunctionEmulator()
 {
 }
 
-FunctionId BuiltInFunctionEmulator::addEmulatedFunction(TOperator op,
-                                                        const TType *param,
-                                                        const char *emulatedFunctionDefinition)
-{
-    FunctionId id(op, param);
-    mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition);
-    return id;
-}
-
-FunctionId BuiltInFunctionEmulator::addEmulatedFunction(TOperator op,
-                                                        const TType *param1,
-                                                        const TType *param2,
-                                                        const char *emulatedFunctionDefinition)
+void BuiltInFunctionEmulator::addEmulatedFunction(const TSymbolUniqueId &uniqueId,
+                                                  const char *emulatedFunctionDefinition)
 {
-    FunctionId id(op, param1, param2);
-    mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition);
-    return id;
-}
-
-FunctionId BuiltInFunctionEmulator::addEmulatedFunctionWithDependency(
-    const FunctionId &dependency,
-    TOperator op,
-    const TType *param1,
-    const TType *param2,
-    const char *emulatedFunctionDefinition)
-{
-    FunctionId id(op, param1, param2);
-    mEmulatedFunctions[id]    = std::string(emulatedFunctionDefinition);
-    mFunctionDependencies[id] = dependency;
-    return id;
+    mEmulatedFunctions[uniqueId.get()] = std::string(emulatedFunctionDefinition);
 }
 
-FunctionId BuiltInFunctionEmulator::addEmulatedFunction(TOperator op,
-                                                        const TType *param1,
-                                                        const TType *param2,
-                                                        const TType *param3,
-                                                        const char *emulatedFunctionDefinition)
-{
-    FunctionId id(op, param1, param2, param3);
-    mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition);
-    return id;
-}
-
-FunctionId BuiltInFunctionEmulator::addEmulatedFunction(TOperator op,
-                                                        const TType *param1,
-                                                        const TType *param2,
-                                                        const TType *param3,
-                                                        const TType *param4,
-                                                        const char *emulatedFunctionDefinition)
-{
-    FunctionId id(op, param1, param2, param3, param4);
-    mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition);
-    return id;
-}
-
-FunctionId BuiltInFunctionEmulator::addEmulatedFunctionWithDependency(
-    const FunctionId &dependency,
-    TOperator op,
-    const TType *param1,
-    const TType *param2,
-    const TType *param3,
-    const TType *param4,
+void BuiltInFunctionEmulator::addEmulatedFunctionWithDependency(
+    const TSymbolUniqueId &dependency,
+    const TSymbolUniqueId &uniqueId,
     const char *emulatedFunctionDefinition)
 {
-    FunctionId id(op, param1, param2, param3, param4);
-    mEmulatedFunctions[id]    = std::string(emulatedFunctionDefinition);
-    mFunctionDependencies[id] = dependency;
-    return id;
+    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
@@ -177,86 +80,61 @@ void BuiltInFunctionEmulator::outputEmul
     {
         const char *body = findEmulatedFunction(function);
         ASSERT(body);
         out << body;
         out << "\n\n";
     }
 }
 
-bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op, const TType &param)
-{
-    return setFunctionCalled(FunctionId(op, &param));
-}
-
-bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op,
-                                                const TType &param1,
-                                                const TType &param2)
-{
-    return setFunctionCalled(FunctionId(op, &param1, &param2));
-}
-
-bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op,
-                                                const TType &param1,
-                                                const TType &param2,
-                                                const TType &param3)
-{
-    return setFunctionCalled(FunctionId(op, &param1, &param2, &param3));
-}
-
-bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op,
-                                                const TType &param1,
-                                                const TType &param2,
-                                                const TType &param3,
-                                                const TType &param4)
-{
-    return setFunctionCalled(FunctionId(op, &param1, &param2, &param3, &param4));
-}
-
-const char *BuiltInFunctionEmulator::findEmulatedFunction(const FunctionId &functionId) const
+const char *BuiltInFunctionEmulator::findEmulatedFunction(int uniqueId) const
 {
     for (const auto &queryFunction : mQueryFunctions)
     {
-        const char *result = queryFunction(functionId);
+        const char *result = queryFunction(uniqueId);
         if (result)
         {
             return result;
         }
     }
 
-    const auto &result = mEmulatedFunctions.find(functionId);
+    const auto &result = mEmulatedFunctions.find(uniqueId);
     if (result != mEmulatedFunctions.end())
     {
         return result->second.c_str();
     }
 
     return nullptr;
 }
 
-bool BuiltInFunctionEmulator::setFunctionCalled(const FunctionId &functionId)
+bool BuiltInFunctionEmulator::setFunctionCalled(const TFunction *function)
 {
-    if (!findEmulatedFunction(functionId))
+    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] == functionId)
+        if (mFunctions[i] == uniqueId)
             return true;
     }
     // If the function depends on another, mark the dependency as called.
-    auto dependency = mFunctionDependencies.find(functionId);
+    auto dependency = mFunctionDependencies.find(uniqueId);
     if (dependency != mFunctionDependencies.end())
     {
         setFunctionCalled((*dependency).second);
     }
-    // Copy the functionId if it needs to be stored, to make sure that the TType pointers inside
-    // remain valid and constant.
-    mFunctions.push_back(functionId.getCopy());
+    mFunctions.push_back(uniqueId);
     return true;
 }
 
 void BuiltInFunctionEmulator::markBuiltInFunctionsForEmulation(TIntermNode *root)
 {
     ASSERT(root);
 
     if (mEmulatedFunctions.empty() && mQueryFunctions.empty())
@@ -279,81 +157,9 @@ void BuiltInFunctionEmulator::addFunctio
 
 // static
 void BuiltInFunctionEmulator::WriteEmulatedFunctionName(TInfoSinkBase &out, const char *name)
 {
     ASSERT(name[strlen(name) - 1] != '(');
     out << name << "_emu";
 }
 
-FunctionId::FunctionId()
-    : mOp(EOpNull),
-      mParam1(StaticType::GetBasic<EbtVoid>()),
-      mParam2(StaticType::GetBasic<EbtVoid>()),
-      mParam3(StaticType::GetBasic<EbtVoid>()),
-      mParam4(StaticType::GetBasic<EbtVoid>())
-{
-}
-
-FunctionId::FunctionId(TOperator op, const TType *param)
-    : mOp(op),
-      mParam1(param),
-      mParam2(StaticType::GetBasic<EbtVoid>()),
-      mParam3(StaticType::GetBasic<EbtVoid>()),
-      mParam4(StaticType::GetBasic<EbtVoid>())
-{
-}
-
-FunctionId::FunctionId(TOperator op, const TType *param1, const TType *param2)
-    : mOp(op),
-      mParam1(param1),
-      mParam2(param2),
-      mParam3(StaticType::GetBasic<EbtVoid>()),
-      mParam4(StaticType::GetBasic<EbtVoid>())
-{
-}
-
-FunctionId::FunctionId(TOperator op, const TType *param1, const TType *param2, const TType *param3)
-    : mOp(op),
-      mParam1(param1),
-      mParam2(param2),
-      mParam3(param3),
-      mParam4(StaticType::GetBasic<EbtVoid>())
-{
-}
-
-FunctionId::FunctionId(TOperator op,
-                       const TType *param1,
-                       const TType *param2,
-                       const TType *param3,
-                       const TType *param4)
-    : mOp(op), mParam1(param1), mParam2(param2), mParam3(param3), mParam4(param4)
-{
-}
-
-bool FunctionId::operator==(const FunctionId &other) const
-{
-    return (mOp == other.mOp && *mParam1 == *other.mParam1 && *mParam2 == *other.mParam2 &&
-            *mParam3 == *other.mParam3 && *mParam4 == *other.mParam4);
-}
-
-bool FunctionId::operator<(const FunctionId &other) const
-{
-    if (mOp != other.mOp)
-        return mOp < other.mOp;
-    if (*mParam1 != *other.mParam1)
-        return *mParam1 < *other.mParam1;
-    if (*mParam2 != *other.mParam2)
-        return *mParam2 < *other.mParam2;
-    if (*mParam3 != *other.mParam3)
-        return *mParam3 < *other.mParam3;
-    if (*mParam4 != *other.mParam4)
-        return *mParam4 < *other.mParam4;
-    return false;  // all fields are equal
-}
-
-FunctionId FunctionId::getCopy() const
-{
-    return FunctionId(mOp, new TType(*mParam1), new TType(*mParam2), new TType(*mParam3),
-                      new TType(*mParam4));
-}
-
 }  // namespace sh
--- a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.h
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.h
@@ -3,92 +3,25 @@
 // 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"
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/ParamType.h"
 
 namespace sh
 {
 
-struct MiniFunctionId
-{
-    constexpr MiniFunctionId(TOperator op         = EOpNull,
-                             ParamType paramType1 = ParamType::Void,
-                             ParamType paramType2 = ParamType::Void,
-                             ParamType paramType3 = ParamType::Void,
-                             ParamType paramType4 = ParamType::Void)
-        : op(op),
-          paramType1(paramType1),
-          paramType2(paramType2),
-          paramType3(paramType3),
-          paramType4(paramType4)
-    {
-    }
-
-    TOperator op;
-    ParamType paramType1;
-    ParamType paramType2;
-    ParamType paramType3;
-    ParamType paramType4;
-};
-
-class FunctionId final
-{
-  public:
-    FunctionId();
-    FunctionId(TOperator op, const TType *param);
-    FunctionId(TOperator op, const TType *param1, const TType *param2);
-    FunctionId(TOperator op, const TType *param1, const TType *param2, const TType *param3);
-    FunctionId(TOperator op,
-               const TType *param1,
-               const TType *param2,
-               const TType *param3,
-               const TType *param4);
+class TIntermNode;
+class TFunction;
+class TSymbolUniqueId;
 
-    FunctionId(const FunctionId &) = default;
-    FunctionId &operator=(const FunctionId &) = default;
-
-    bool operator==(const FunctionId &other) const;
-    bool operator<(const FunctionId &other) const;
-
-    FunctionId getCopy() const;
-
-  private:
-    friend bool operator==(const MiniFunctionId &miniId, const FunctionId &functionId);
-    TOperator mOp;
-
-    // The memory that these TType objects use is freed by PoolAllocator. The
-    // BuiltInFunctionEmulator's lifetime can extend until after the memory pool is freed, but
-    // that's not an issue since this class never destructs these objects.
-    const TType *mParam1;
-    const TType *mParam2;
-    const TType *mParam3;
-    const TType *mParam4;
-};
-
-inline bool operator==(ParamType paramType, const TType *type)
-{
-    return SameParamType(paramType, type->getBasicType(), type->getNominalSize(),
-                         type->getSecondarySize());
-}
-
-inline bool operator==(const MiniFunctionId &miniId, const FunctionId &functionId)
-{
-    return miniId.op == functionId.mOp && miniId.paramType1 == functionId.mParam1 &&
-           miniId.paramType2 == functionId.mParam2 && miniId.paramType3 == functionId.mParam3 &&
-           miniId.paramType4 == functionId.mParam4;
-}
-
-using BuiltinQueryFunc = const char *(const FunctionId &);
+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
 {
@@ -103,81 +36,45 @@ class BuiltInFunctionEmulator
     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.
-    FunctionId addEmulatedFunction(TOperator op,
-                                   const TType *param,
-                                   const char *emulatedFunctionDefinition);
-    FunctionId addEmulatedFunction(TOperator op,
-                                   const TType *param1,
-                                   const TType *param2,
-                                   const char *emulatedFunctionDefinition);
-    FunctionId addEmulatedFunction(TOperator op,
-                                   const TType *param1,
-                                   const TType *param2,
-                                   const TType *param3,
-                                   const char *emulatedFunctionDefinition);
-    FunctionId addEmulatedFunction(TOperator op,
-                                   const TType *param1,
-                                   const TType *param2,
-                                   const TType *param3,
-                                   const TType *param4,
-                                   const char *emulatedFunctionDefinition);
+    void addEmulatedFunction(const TSymbolUniqueId &uniqueId,
+                             const char *emulatedFunctionDefinition);
 
-    FunctionId addEmulatedFunctionWithDependency(const FunctionId &dependency,
-                                                 TOperator op,
-                                                 const TType *param1,
-                                                 const TType *param2,
-                                                 const char *emulatedFunctionDefinition);
-    FunctionId addEmulatedFunctionWithDependency(const FunctionId &dependency,
-                                                 TOperator op,
-                                                 const TType *param1,
-                                                 const TType *param2,
-                                                 const TType *param3,
-                                                 const TType *param4,
-                                                 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(TOperator op, const TType &param);
-    bool setFunctionCalled(TOperator op, const TType &param1, const TType &param2);
-    bool setFunctionCalled(TOperator op,
-                           const TType &param1,
-                           const TType &param2,
-                           const TType &param3);
-    bool setFunctionCalled(TOperator op,
-                           const TType &param1,
-                           const TType &param2,
-                           const TType &param3,
-                           const TType &param4);
+    bool setFunctionCalled(const TFunction *function);
+    bool setFunctionCalled(int uniqueId);
 
-    bool setFunctionCalled(const FunctionId &functionId);
+    const char *findEmulatedFunction(int uniqueId) const;
 
-    const char *findEmulatedFunction(const FunctionId &functionId) const;
-
-    // Map from function id to emulated function definition
-    std::map<FunctionId, std::string> mEmulatedFunctions;
+    // 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<FunctionId, FunctionId> mFunctionDependencies;
+    std::map<int, int> mFunctionDependencies;
 
     // Called function ids
-    std::vector<FunctionId> mFunctions;
+    std::vector<int> mFunctions;
 
     // Constexpr function tables.
     std::vector<BuiltinQueryFunc *> mQueryFunctions;
 };
 
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
--- a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
@@ -2,178 +2,159 @@
 // Copyright (c) 2002-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.
 //
 
 #include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
 #include "angle_gl.h"
 #include "compiler/translator/BuiltInFunctionEmulator.h"
-#include "compiler/translator/SymbolTable.h"
-#include "compiler/translator/StaticType.h"
 #include "compiler/translator/VersionGLSL.h"
+#include "compiler/translator/tree_util/BuiltIn_autogen.h"
 
 namespace sh
 {
 
 void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
                                                       sh::GLenum shaderType)
 {
     if (shaderType == GL_VERTEX_SHADER)
     {
-        const TType *int1 = StaticType::GetBasic<EbtInt>();
-        emu->addEmulatedFunction(EOpAbs, int1, "int abs_emu(int x) { return x * sign(x); }");
+        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;
 
-    const TType *float1 = StaticType::GetBasic<EbtFloat>();
-    const TType *float2 = StaticType::GetBasic<EbtFloat, 2>();
-    const TType *float3 = StaticType::GetBasic<EbtFloat, 3>();
-    const TType *float4 = StaticType::GetBasic<EbtFloat, 4>();
-
     // !(x > 0.0 || x < 0.0 || x == 0.0) will be optimized and always equal to false.
     emu->addEmulatedFunction(
-        EOpIsnan, float1,
+        BuiltInId::isnan_Float1,
         "bool isnan_emu(float x) { return (x > 0.0 || x < 0.0) ? false : x != 0.0; }");
     emu->addEmulatedFunction(
-        EOpIsnan, float2,
+        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(
-        EOpIsnan, float3,
+        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(
-        EOpIsnan, float4,
+        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)
 {
-    const TType *float1 = StaticType::GetBasic<EbtFloat>();
-    auto floatFuncId    = emu->addEmulatedFunction(
-        EOpAtan, 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<const TType *, 5> floatVecs = {
-        nullptr,
-        nullptr,
-        StaticType::GetBasic<EbtFloat, 2>(),
-        StaticType::GetBasic<EbtFloat, 3>(),
-        StaticType::GetBasic<EbtFloat, 4>(),
+    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)
     {
-        const TType *floatVec = floatVecs[dim];
         std::stringstream ss;
         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(floatFuncId, EOpAtan, floatVec, floatVec,
+        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)
     {
-        const TType *float2 = StaticType::GetBasic<EbtFloat, 2>();
-        const TType *uint1  = StaticType::GetBasic<EbtUInt>();
-
         // clang-format off
-        emu->addEmulatedFunction(EOpPackUnorm2x16, float2,
+        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(EOpUnpackUnorm2x16, uint1,
+        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)
     {
-        const TType *float2 = StaticType::GetBasic<EbtFloat, 2>();
-        const TType *uint1  = StaticType::GetBasic<EbtUInt>();
-
         // clang-format off
-        emu->addEmulatedFunction(EOpPackSnorm2x16, float2,
+        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(EOpUnpackSnorm2x16, uint1,
+        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"
@@ -184,17 +165,17 @@ void InitBuiltInFunctionEmulatorForGLSLM
             "    #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(EOpPackHalf2x16, float2,
+        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"
@@ -231,17 +212,17 @@ void InitBuiltInFunctionEmulatorForGLSLM
             "    #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(EOpUnpackHalf2x16, uint1,
+        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"
--- a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
@@ -1,142 +1,131 @@
 //
 // Copyright (c) 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/BuiltInFunctionEmulatorHLSL.h"
-#include "compiler/translator/SymbolTable.h"
 #include "compiler/translator/VersionGLSL.h"
+#include "compiler/translator/tree_util/BuiltIn_autogen.h"
 
 namespace sh
 {
 
 // Defined in emulated_builtin_functions_hlsl_autogen.cpp.
-const char *FindHLSLFunction(const FunctionId &functionID);
+const char *FindHLSLFunction(int uniqueId);
 
 void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu,
                                                         int targetGLSLVersion)
 {
     if (targetGLSLVersion < GLSL_VERSION_130)
         return;
 
-    TType *float1 = new TType(EbtFloat);
-    TType *float2 = new TType(EbtFloat, 2);
-    TType *float3 = new TType(EbtFloat, 3);
-    TType *float4 = new TType(EbtFloat, 4);
-
-    emu->addEmulatedFunction(EOpIsnan, float1,
+    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(
-        EOpIsnan, float2,
+        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(
-        EOpIsnan, float3,
+        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(
-        EOpIsnan, float4,
+        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)
 {
-    TType *int1   = new TType(EbtInt);
-    TType *int2   = new TType(EbtInt, 2);
-    TType *int3   = new TType(EbtInt, 3);
-    TType *int4   = new TType(EbtInt, 4);
-    TType *uint1  = new TType(EbtUInt);
-    TType *uint2  = new TType(EbtUInt, 2);
-    TType *uint3  = new TType(EbtUInt, 3);
-    TType *uint4  = new TType(EbtUInt, 4);
-
     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
-    FunctionId umulExtendedUint1 = emu->addEmulatedFunction(
-        EOpUmulExtended, 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->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(
-        umulExtendedUint1, EOpUmulExtended, uint2, uint2, uint2, uint2,
+        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(
-        umulExtendedUint1, EOpUmulExtended, uint3, uint3, uint3, uint3,
+        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(
-        umulExtendedUint1, EOpUmulExtended, uint4, uint4, uint4, uint4,
+        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.
-    FunctionId imulExtendedInt1 = emu->addEmulatedFunctionWithDependency(
-        umulExtendedUint1, EOpImulExtended, int1, int1, int1, int1,
+    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"
@@ -151,32 +140,32 @@ void InitBuiltInFunctionEmulatorForHLSL(
         "        }\n"
         "        else\n"
         "        {\n"
         "            lsb += 1;\n"
         "        }\n"
         "    }\n"
         "}\n");
     emu->addEmulatedFunctionWithDependency(
-        imulExtendedInt1, EOpImulExtended, int2, int2, int2, int2,
+        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(
-        imulExtendedInt1, EOpImulExtended, int3, int3, int3, int3,
+        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(
-        imulExtendedInt1, EOpImulExtended, int4, int4, int4, int4,
+        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");
 }
--- a/gfx/angle/checkout/src/compiler/translator/CallDAG.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/CallDAG.cpp
@@ -6,18 +6,18 @@
 
 // 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/IntermTraverse.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
 {
@@ -111,26 +111,23 @@ class CallDAG::CallDAGCreator : public T
         mCurrentFunction->name           = node->getFunction()->name();
         mCurrentFunction->definitionNode = node;
 
         node->getBody()->traverse(this);
         mCurrentFunction = nullptr;
         return false;
     }
 
-    bool visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node) override
+    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();
-
-        // No need to traverse the parameters.
-        return false;
     }
 
     // Track functions called from another function.
     bool visitAggregate(Visit visit, TIntermAggregate *node) override
     {
         if (node->getOp() == EOpCallFunctionInAST)
         {
             // Function call, add the callees
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ClampFragDepth.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-//
-// Copyright (c) 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/ClampFragDepth.h"
-
-#include "compiler/translator/FindSymbolNode.h"
-#include "compiler/translator/ImmutableString.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/RunAtTheEndOfShader.h"
-#include "compiler/translator/SymbolTable.h"
-
-namespace sh
-{
-
-void ClampFragDepth(TIntermBlock *root, TSymbolTable *symbolTable)
-{
-    // Only clamp gl_FragDepth if it's used in the shader.
-    if (!FindSymbolNode(root, ImmutableString("gl_FragDepth")))
-    {
-        return;
-    }
-
-    TIntermSymbol *fragDepthNode =
-        ReferenceBuiltInVariable(ImmutableString("gl_FragDepth"), *symbolTable, 300);
-
-    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 = new TIntermSequence();
-    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);
-
-    RunAtTheEndOfShader(root, assignFragDepth, symbolTable);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ClampFragDepth.h
+++ /dev/null
@@ -1,24 +0,0 @@
-//
-// Copyright (c) 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_CLAMPFRAGDEPTH_H_
-#define COMPILER_TRANSLATOR_CLAMPFRAGDEPTH_H_
-
-namespace sh
-{
-
-class TIntermBlock;
-class TSymbolTable;
-
-void ClampFragDepth(TIntermBlock *root, TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_CLAMPFRAGDEPTH_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ClampPointSize.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// Copyright (c) 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/ClampPointSize.h"
-
-#include "compiler/translator/FindSymbolNode.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/RunAtTheEndOfShader.h"
-#include "compiler/translator/SymbolTable.h"
-
-namespace sh
-{
-
-void ClampPointSize(TIntermBlock *root, float maxPointSize, TSymbolTable *symbolTable)
-{
-    // Only clamp gl_PointSize if it's used in the shader.
-    if (!FindSymbolNode(root, ImmutableString("gl_PointSize")))
-    {
-        return;
-    }
-
-    TIntermSymbol *pointSizeNode =
-        ReferenceBuiltInVariable(ImmutableString("gl_PointSize"), *symbolTable, 100);
-
-    TConstantUnion *maxPointSizeConstant = new TConstantUnion();
-    maxPointSizeConstant->setFConst(maxPointSize);
-    TIntermConstantUnion *maxPointSizeNode =
-        new TIntermConstantUnion(maxPointSizeConstant, TType(EbtFloat, EbpHigh, EvqConst));
-
-    // min(gl_PointSize, maxPointSize)
-    TIntermSequence *minArguments = new TIntermSequence();
-    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);
-
-    RunAtTheEndOfShader(root, assignPointSize, symbolTable);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ClampPointSize.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//
-// Copyright (c) 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_CLAMPPOINTSIZE_H_
-#define COMPILER_TRANSLATOR_CLAMPPOINTSIZE_H_
-
-namespace sh
-{
-
-class TIntermBlock;
-class TSymbolTable;
-
-void ClampPointSize(TIntermBlock *root, float maxPointSize, TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_CLAMPPOINTSIZE_H_
--- a/gfx/angle/checkout/src/compiler/translator/CollectVariables.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/CollectVariables.cpp
@@ -5,18 +5,18 @@
 //
 // 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/IntermTraverse.h"
 #include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
 #include "compiler/translator/util.h"
 
 namespace sh
 {
 
 namespace
 {
 
@@ -63,44 +63,46 @@ VarT *FindVariable(const ImmutableString
     {
         if (name == (*infoList)[ii].name)
             return &((*infoList)[ii]);
     }
 
     return nullptr;
 }
 
-// Note that this shouldn't be called for interface blocks - static use information is collected for
+// Note that this shouldn't be called for interface blocks - active information is collected for
 // individual fields in case of interface blocks.
-void MarkStaticallyUsed(ShaderVariable *variable)
+void MarkActive(ShaderVariable *variable)
 {
-    if (!variable->staticUse)
+    if (!variable->active)
     {
         if (variable->isStruct())
         {
             // Conservatively assume all fields are statically used as well.
             for (auto &field : variable->fields)
             {
-                MarkStaticallyUsed(&field);
+                MarkActive(&field);
             }
         }
-        variable->staticUse = true;
+        ASSERT(variable->staticUse);
+        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);
 }
 
 // Traverses the intermediate tree to collect all attributes, uniforms, varyings, fragment outputs,
 // and interface blocks.
 class CollectVariablesTraverser : public TIntermTraverser
 {
   public:
@@ -109,50 +111,53 @@ class CollectVariablesTraverser : public
                               std::vector<Uniform> *uniforms,
                               std::vector<Varying> *inputVaryings,
                               std::vector<Varying> *outputVaryings,
                               std::vector<InterfaceBlock> *uniformBlocks,
                               std::vector<InterfaceBlock> *shaderStorageBlocks,
                               std::vector<InterfaceBlock> *inBlocks,
                               ShHashFunction64 hashFunction,
                               TSymbolTable *symbolTable,
-                              int shaderVersion,
                               GLenum shaderType,
                               const TExtensionBehavior &extensionBehavior);
 
+    bool visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *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, ShaderVariable *variableOut) const;
+    void setFieldOrVariableProperties(const TType &type,
+                                      bool staticUse,
+                                      ShaderVariable *variableOut) const;
     void setFieldProperties(const TType &type,
                             const ImmutableString &name,
+                            bool staticUse,
                             ShaderVariable *variableOut) const;
     void setCommonVariableProperties(const TType &type,
                                      const TVariable &variable,
                                      ShaderVariable *variableOut) const;
 
     Attribute recordAttribute(const TIntermSymbol &variable) const;
     OutputVariable recordOutputVariable(const TIntermSymbol &variable) const;
     Varying recordVarying(const TIntermSymbol &variable) const;
     void recordInterfaceBlock(const char *instanceName,
                               const TType &interfaceBlockType,
                               InterfaceBlock *interfaceBlock) const;
     Uniform recordUniform(const TIntermSymbol &variable) const;
 
-    void setBuiltInInfoFromSymbolTable(const ImmutableString &name, ShaderVariable *info);
+    void setBuiltInInfoFromSymbol(const TVariable &variable, ShaderVariable *info);
 
-    void recordBuiltInVaryingUsed(const ImmutableString &name,
+    void recordBuiltInVaryingUsed(const TVariable &variable,
                                   bool *addedFlag,
                                   std::vector<Varying> *varyings);
-    void recordBuiltInFragmentOutputUsed(const ImmutableString &name, bool *addedFlag);
-    void recordBuiltInAttributeUsed(const ImmutableString &name, bool *addedFlag);
+    void recordBuiltInFragmentOutputUsed(const TVariable &variable, bool *addedFlag);
+    void recordBuiltInAttributeUsed(const TVariable &variable, bool *addedFlag);
     InterfaceBlock *recordGLInUsed(const TType &glInType);
     InterfaceBlock *findNamedInterfaceBlock(const ImmutableString &name) const;
 
     std::vector<Attribute> *mAttribs;
     std::vector<OutputVariable> *mOutputVariables;
     std::vector<Uniform> *mUniforms;
     std::vector<Varying> *mInputVaryings;
     std::vector<Varying> *mOutputVaryings;
@@ -191,33 +196,31 @@ class CollectVariablesTraverser : public
     bool mInvocationIDAdded;
 
     // Geometry Shader and Fragment Shader builtins
     bool mPrimitiveIDAdded;
     bool mLayerAdded;
 
     ShHashFunction64 mHashFunction;
 
-    int mShaderVersion;
     GLenum mShaderType;
     const TExtensionBehavior &mExtensionBehavior;
 };
 
 CollectVariablesTraverser::CollectVariablesTraverser(
     std::vector<sh::Attribute> *attribs,
     std::vector<sh::OutputVariable> *outputVariables,
     std::vector<sh::Uniform> *uniforms,
     std::vector<sh::Varying> *inputVaryings,
     std::vector<sh::Varying> *outputVaryings,
     std::vector<sh::InterfaceBlock> *uniformBlocks,
     std::vector<sh::InterfaceBlock> *shaderStorageBlocks,
     std::vector<sh::InterfaceBlock> *inBlocks,
     ShHashFunction64 hashFunction,
     TSymbolTable *symbolTable,
-    int shaderVersion,
     GLenum shaderType,
     const TExtensionBehavior &extensionBehavior)
     : TIntermTraverser(true, false, false, symbolTable),
       mAttribs(attribs),
       mOutputVariables(outputVariables),
       mUniforms(uniforms),
       mInputVaryings(inputVaryings),
       mOutputVaryings(outputVaryings),
@@ -240,112 +243,116 @@ CollectVariablesTraverser::CollectVariab
       mSecondaryFragColorEXTAdded(false),
       mSecondaryFragDataEXTAdded(false),
       mPerVertexInAdded(false),
       mPrimitiveIDInAdded(false),
       mInvocationIDAdded(false),
       mPrimitiveIDAdded(false),
       mLayerAdded(false),
       mHashFunction(hashFunction),
-      mShaderVersion(shaderVersion),
       mShaderType(shaderType),
       mExtensionBehavior(extensionBehavior)
 {
 }
 
 std::string CollectVariablesTraverser::getMappedName(const TSymbol *symbol) const
 {
     return HashName(symbol, mHashFunction, nullptr).data();
 }
 
-void CollectVariablesTraverser::setBuiltInInfoFromSymbolTable(const ImmutableString &name,
-                                                              ShaderVariable *info)
+void CollectVariablesTraverser::setBuiltInInfoFromSymbol(const TVariable &variable,
+                                                         ShaderVariable *info)
 {
-    const TVariable *symbolTableVar =
-        reinterpret_cast<const TVariable *>(mSymbolTable->findBuiltIn(name, mShaderVersion));
-    ASSERT(symbolTableVar);
-    const TType &type = symbolTableVar->getType();
+    const TType &type = variable.getType();
 
-    info->name       = name.data();
-    info->mappedName = name.data();
+    info->name       = variable.name().data();
+    info->mappedName = variable.name().data();
     info->type       = GLVariableType(type);
     info->precision = GLVariablePrecision(type);
     if (auto *arraySizes = type.getArraySizes())
     {
         info->arraySizes.assign(arraySizes->begin(), arraySizes->end());
     }
 }
 
-void CollectVariablesTraverser::recordBuiltInVaryingUsed(const ImmutableString &name,
+void CollectVariablesTraverser::recordBuiltInVaryingUsed(const TVariable &variable,
                                                          bool *addedFlag,
                                                          std::vector<Varying> *varyings)
 {
     ASSERT(varyings);
     if (!(*addedFlag))
     {
         Varying info;
-        setBuiltInInfoFromSymbolTable(name, &info);
+        setBuiltInInfoFromSymbol(variable, &info);
         info.staticUse   = true;
-        info.isInvariant = mSymbolTable->isVaryingInvariant(name);
+        info.active      = true;
+        info.isInvariant = mSymbolTable->isVaryingInvariant(variable.name());
         varyings->push_back(info);
         (*addedFlag) = true;
     }
 }
 
-void CollectVariablesTraverser::recordBuiltInFragmentOutputUsed(const ImmutableString &name,
+void CollectVariablesTraverser::recordBuiltInFragmentOutputUsed(const TVariable &variable,
                                                                 bool *addedFlag)
 {
     if (!(*addedFlag))
     {
         OutputVariable info;
-        setBuiltInInfoFromSymbolTable(name, &info);
+        setBuiltInInfoFromSymbol(variable, &info);
         info.staticUse = true;
+        info.active    = true;
         mOutputVariables->push_back(info);
         (*addedFlag) = true;
     }
 }
 
-void CollectVariablesTraverser::recordBuiltInAttributeUsed(const ImmutableString &name,
+void CollectVariablesTraverser::recordBuiltInAttributeUsed(const TVariable &variable,
                                                            bool *addedFlag)
 {
     if (!(*addedFlag))
     {
         Attribute info;
-        setBuiltInInfoFromSymbolTable(name, &info);
+        setBuiltInInfoFromSymbol(variable, &info);
         info.staticUse = true;
+        info.active    = true;
         info.location  = -1;
         mAttribs->push_back(info);
         (*addedFlag) = true;
     }
 }
 
 InterfaceBlock *CollectVariablesTraverser::recordGLInUsed(const TType &glInType)
 {
     if (!mPerVertexInAdded)
     {
         ASSERT(glInType.getQualifier() == EvqPerVertexIn);
         InterfaceBlock info;
         recordInterfaceBlock("gl_in", glInType, &info);
-        info.staticUse = true;
 
         mPerVertexInAdded = true;
         mInBlocks->push_back(info);
         return &mInBlocks->back();
     }
     else
     {
         return FindVariable(ImmutableString("gl_PerVertex"), mInBlocks);
     }
 }
 
-// We want to check whether a uniform/varying is statically used
-// because we only count the used ones in packing computing.
-// Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count
-// toward varying counting if they are statically used in a fragment
-// shader.
+bool CollectVariablesTraverser::visitInvariantDeclaration(Visit visit,
+                                                          TIntermInvariantDeclaration *node)
+{
+    // We should not mark variables as active just based on an invariant 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.
@@ -380,37 +387,41 @@ void CollectVariablesTraverser::visitSym
         {
             Uniform 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;
         }
@@ -445,148 +456,126 @@ void CollectVariablesTraverser::visitSym
             case EvqBuffer:
             {
                 const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
                 var =
                     FindVariableInInterfaceBlock(symbolName, interfaceBlock, mShaderStorageBlocks);
             }
             break;
             case EvqFragCoord:
-                recordBuiltInVaryingUsed(ImmutableString("gl_FragCoord"), &mFragCoordAdded,
-                                         mInputVaryings);
+                recordBuiltInVaryingUsed(symbol->variable(), &mFragCoordAdded, mInputVaryings);
                 return;
             case EvqFrontFacing:
-                recordBuiltInVaryingUsed(ImmutableString("gl_FrontFacing"), &mFrontFacingAdded,
-                                         mInputVaryings);
+                recordBuiltInVaryingUsed(symbol->variable(), &mFrontFacingAdded, mInputVaryings);
                 return;
             case EvqPointCoord:
-                recordBuiltInVaryingUsed(ImmutableString("gl_PointCoord"), &mPointCoordAdded,
-                                         mInputVaryings);
+                recordBuiltInVaryingUsed(symbol->variable(), &mPointCoordAdded, mInputVaryings);
                 return;
             case EvqInstanceID:
                 // Whenever the SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW option is set,
                 // gl_InstanceID is added inside expressions to initialize ViewID_OVR and
-                // InstanceID. gl_InstanceID is not added to the symbol table for ESSL1 shaders
-                // which makes it necessary to populate the type information explicitly instead of
-                // extracting it from the symbol table.
-                if (!mInstanceIDAdded)
-                {
-                    Attribute info;
-                    const char kName[] = "gl_InstanceID";
-                    info.name          = kName;
-                    info.mappedName    = kName;
-                    info.type          = GL_INT;
-                    info.precision     = GL_HIGH_INT;  // Defined by spec.
-                    info.staticUse     = true;
-                    info.location      = -1;
-                    mAttribs->push_back(info);
-                    mInstanceIDAdded = true;
-                }
+                // InstanceID. Note that gl_InstanceID is not added to the symbol table for ESSL1
+                // shaders.
+                recordBuiltInAttributeUsed(symbol->variable(), &mInstanceIDAdded);
                 return;
             case EvqVertexID:
-                recordBuiltInAttributeUsed(ImmutableString("gl_VertexID"), &mVertexIDAdded);
+                recordBuiltInAttributeUsed(symbol->variable(), &mVertexIDAdded);
                 return;
             case EvqPosition:
-                recordBuiltInVaryingUsed(ImmutableString("gl_Position"), &mPositionAdded,
-                                         mOutputVaryings);
+                recordBuiltInVaryingUsed(symbol->variable(), &mPositionAdded, mOutputVaryings);
                 return;
             case EvqPointSize:
-                recordBuiltInVaryingUsed(ImmutableString("gl_PointSize"), &mPointSizeAdded,
-                                         mOutputVaryings);
+                recordBuiltInVaryingUsed(symbol->variable(), &mPointSizeAdded, mOutputVaryings);
                 return;
             case EvqLastFragData:
-                recordBuiltInVaryingUsed(ImmutableString("gl_LastFragData"), &mLastFragDataAdded,
-                                         mInputVaryings);
+                recordBuiltInVaryingUsed(symbol->variable(), &mLastFragDataAdded, mInputVaryings);
                 return;
             case EvqFragColor:
-                recordBuiltInFragmentOutputUsed(ImmutableString("gl_FragColor"), &mFragColorAdded);
+                recordBuiltInFragmentOutputUsed(symbol->variable(), &mFragColorAdded);
                 return;
             case EvqFragData:
                 if (!mFragDataAdded)
                 {
                     OutputVariable info;
-                    setBuiltInInfoFromSymbolTable(ImmutableString("gl_FragData"), &info);
+                    setBuiltInInfoFromSymbol(symbol->variable(), &info);
                     if (!IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers))
                     {
                         ASSERT(info.arraySizes.size() == 1u);
                         info.arraySizes.back() = 1u;
                     }
                     info.staticUse = true;
+                    info.active    = true;
                     mOutputVariables->push_back(info);
                     mFragDataAdded = true;
                 }
                 return;
             case EvqFragDepthEXT:
-                recordBuiltInFragmentOutputUsed(ImmutableString("gl_FragDepthEXT"),
-                                                &mFragDepthEXTAdded);
+                recordBuiltInFragmentOutputUsed(symbol->variable(), &mFragDepthEXTAdded);
                 return;
             case EvqFragDepth:
-                recordBuiltInFragmentOutputUsed(ImmutableString("gl_FragDepth"), &mFragDepthAdded);
+                recordBuiltInFragmentOutputUsed(symbol->variable(), &mFragDepthAdded);
                 return;
             case EvqSecondaryFragColorEXT:
-                recordBuiltInFragmentOutputUsed(ImmutableString("gl_SecondaryFragColorEXT"),
-                                                &mSecondaryFragColorEXTAdded);
+                recordBuiltInFragmentOutputUsed(symbol->variable(), &mSecondaryFragColorEXTAdded);
                 return;
             case EvqSecondaryFragDataEXT:
-                recordBuiltInFragmentOutputUsed(ImmutableString("gl_SecondaryFragDataEXT"),
-                                                &mSecondaryFragDataEXTAdded);
+                recordBuiltInFragmentOutputUsed(symbol->variable(), &mSecondaryFragDataEXTAdded);
                 return;
             case EvqInvocationID:
-                recordBuiltInVaryingUsed(ImmutableString("gl_InvocationID"), &mInvocationIDAdded,
-                                         mInputVaryings);
+                recordBuiltInVaryingUsed(symbol->variable(), &mInvocationIDAdded, mInputVaryings);
                 break;
             case EvqPrimitiveIDIn:
-                recordBuiltInVaryingUsed(ImmutableString("gl_PrimitiveIDIn"), &mPrimitiveIDInAdded,
-                                         mInputVaryings);
+                recordBuiltInVaryingUsed(symbol->variable(), &mPrimitiveIDInAdded, mInputVaryings);
                 break;
             case EvqPrimitiveID:
                 if (mShaderType == GL_GEOMETRY_SHADER_EXT)
                 {
-                    recordBuiltInVaryingUsed(ImmutableString("gl_PrimitiveID"), &mPrimitiveIDAdded,
+                    recordBuiltInVaryingUsed(symbol->variable(), &mPrimitiveIDAdded,
                                              mOutputVaryings);
                 }
                 else
                 {
                     ASSERT(mShaderType == GL_FRAGMENT_SHADER);
-                    recordBuiltInVaryingUsed(ImmutableString("gl_PrimitiveID"), &mPrimitiveIDAdded,
+                    recordBuiltInVaryingUsed(symbol->variable(), &mPrimitiveIDAdded,
                                              mInputVaryings);
                 }
                 break;
             case EvqLayer:
                 if (mShaderType == GL_GEOMETRY_SHADER_EXT)
                 {
-                    recordBuiltInVaryingUsed(ImmutableString("gl_Layer"), &mLayerAdded,
-                                             mOutputVaryings);
+                    recordBuiltInVaryingUsed(symbol->variable(), &mLayerAdded, mOutputVaryings);
                 }
                 else if (mShaderType == GL_FRAGMENT_SHADER)
                 {
-                    recordBuiltInVaryingUsed(ImmutableString("gl_Layer"), &mLayerAdded,
-                                             mInputVaryings);
+                    recordBuiltInVaryingUsed(symbol->variable(), &mLayerAdded, mInputVaryings);
                 }
                 else
                 {
                     ASSERT(mShaderType == GL_VERTEX_SHADER &&
                            IsExtensionEnabled(mExtensionBehavior, TExtension::OVR_multiview));
                 }
                 break;
             default:
                 break;
         }
     }
     if (var)
     {
-        MarkStaticallyUsed(var);
+        MarkActive(var);
     }
 }
 
 void CollectVariablesTraverser::setFieldOrVariableProperties(const TType &type,
+                                                             bool staticUse,
                                                              ShaderVariable *variableOut) const
 {
     ASSERT(variableOut);
 
+    variableOut->staticUse = staticUse;
+
     const TStructure *structure = type.getStruct();
     if (!structure)
     {
         variableOut->type      = GLVariableType(type);
         variableOut->precision = GLVariablePrecision(type);
     }
     else
     {
@@ -599,43 +588,45 @@ void CollectVariablesTraverser::setField
 
         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(), &fieldVariable);
+            setFieldProperties(*field->type(), field->name(), staticUse, &fieldVariable);
             variableOut->fields.push_back(fieldVariable);
         }
     }
     if (auto *arraySizes = type.getArraySizes())
     {
         variableOut->arraySizes.assign(arraySizes->begin(), arraySizes->end());
     }
 }
 
 void CollectVariablesTraverser::setFieldProperties(const TType &type,
                                                    const ImmutableString &name,
+                                                   bool staticUse,
                                                    ShaderVariable *variableOut) const
 {
     ASSERT(variableOut);
-    setFieldOrVariableProperties(type, variableOut);
+    setFieldOrVariableProperties(type, staticUse, variableOut);
     variableOut->name.assign(name.data(), name.length());
     variableOut->mappedName = HashName(name, mHashFunction, nullptr).data();
 }
 
 void CollectVariablesTraverser::setCommonVariableProperties(const TType &type,
                                                             const TVariable &variable,
                                                             ShaderVariable *variableOut) const
 {
     ASSERT(variableOut);
 
-    setFieldOrVariableProperties(type, variableOut);
+    variableOut->staticUse = mSymbolTable->isStaticallyUsed(variable);
+    setFieldOrVariableProperties(type, variableOut->staticUse, variableOut);
     ASSERT(variable.symbolType() != SymbolType::Empty);
     variableOut->name.assign(variable.name().data(), variable.name().length());
     variableOut->mappedName = getMappedName(&variable);
 }
 
 Attribute CollectVariablesTraverser::recordAttribute(const TIntermSymbol &variable) const
 {
     const TType &type = variable.getType();
@@ -701,41 +692,73 @@ void CollectVariablesTraverser::recordIn
     const TInterfaceBlock *blockType = interfaceBlockType.getInterfaceBlock();
     ASSERT(blockType);
 
     interfaceBlock->name       = blockType->name().data();
     interfaceBlock->mappedName = getMappedName(blockType);
     if (instanceName != nullptr)
     {
         interfaceBlock->instanceName = instanceName;
+        const TSymbol *blockSymbol   = nullptr;
+        if (strncmp(instanceName, "gl_in", 5u) == 0)
+        {
+            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;
+            }
+        }
+
         InterfaceBlockField fieldVariable;
-        setFieldProperties(fieldType, field->name(), &fieldVariable);
+        setFieldProperties(fieldType, field->name(), staticUse, &fieldVariable);
         fieldVariable.isRowMajorLayout =
             (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
         interfaceBlock->fields.push_back(fieldVariable);
     }
+    if (anyFieldStaticallyUsed)
+    {
+        interfaceBlock->staticUse = true;
+    }
 }
 
 Uniform CollectVariablesTraverser::recordUniform(const TIntermSymbol &variable) const
 {
     Uniform uniform;
     setCommonVariableProperties(variable.getType(), variable.variable(), &uniform);
     uniform.binding  = variable.getType().getLayoutQualifier().binding;
     uniform.location = variable.getType().getLayoutQualifier().location;
@@ -843,17 +866,17 @@ InterfaceBlock *CollectVariablesTraverse
     }
     return namedBlock;
 }
 
 bool CollectVariablesTraverser::visitBinary(Visit, TIntermBinary *binaryNode)
 {
     if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
     {
-        // NOTE: we do not determine static use for individual blocks of an array
+        // 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;
 
@@ -877,20 +900,25 @@ bool CollectVariablesTraverser::visitBin
         }
 
         const TInterfaceBlock *interfaceBlock = blockNode->getType().getInterfaceBlock();
         if (!namedBlock)
         {
             namedBlock = findNamedInterfaceBlock(interfaceBlock->name());
         }
         ASSERT(namedBlock);
-        namedBlock->staticUse   = true;
+        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
         namedBlock->fields[fieldIndex].staticUse = true;
+        namedBlock->fields[fieldIndex].active    = true;
 
         if (traverseIndexExpression)
         {
             ASSERT(interfaceIndexingNode);
             interfaceIndexingNode->getRight()->traverse(this);
         }
         return false;
     }
@@ -906,20 +934,18 @@ void CollectVariables(TIntermBlock *root
                       std::vector<Uniform> *uniforms,
                       std::vector<Varying> *inputVaryings,
                       std::vector<Varying> *outputVaryings,
                       std::vector<InterfaceBlock> *uniformBlocks,
                       std::vector<InterfaceBlock> *shaderStorageBlocks,
                       std::vector<InterfaceBlock> *inBlocks,
                       ShHashFunction64 hashFunction,
                       TSymbolTable *symbolTable,
-                      int shaderVersion,
                       GLenum shaderType,
                       const TExtensionBehavior &extensionBehavior)
 {
     CollectVariablesTraverser collect(attributes, outputVariables, uniforms, inputVaryings,
                                       outputVaryings, uniformBlocks, shaderStorageBlocks, inBlocks,
-                                      hashFunction, symbolTable, shaderVersion, shaderType,
-                                      extensionBehavior);
+                                      hashFunction, symbolTable, shaderType, extensionBehavior);
     root->traverse(&collect);
 }
 
 }  // namespace sh
--- a/gfx/angle/checkout/src/compiler/translator/CollectVariables.h
+++ b/gfx/angle/checkout/src/compiler/translator/CollectVariables.h
@@ -24,14 +24,13 @@ void CollectVariables(TIntermBlock *root
                       std::vector<Uniform> *uniforms,
                       std::vector<Varying> *inputVaryings,
                       std::vector<Varying> *outputVaryings,
                       std::vector<InterfaceBlock> *uniformBlocks,
                       std::vector<InterfaceBlock> *shaderStorageBlocks,
                       std::vector<InterfaceBlock> *inBlocks,
                       ShHashFunction64 hashFunction,
                       TSymbolTable *symbolTable,
-                      int shaderVersion,
                       GLenum shaderType,
                       const TExtensionBehavior &extensionBehavior);
 }
 
 #endif  // COMPILER_TRANSLATOR_COLLECTVARIABLES_H_
--- a/gfx/angle/checkout/src/compiler/translator/Compiler.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/Compiler.cpp
@@ -5,53 +5,53 @@
 //
 
 #include "compiler/translator/Compiler.h"
 
 #include <sstream>
 
 #include "angle_gl.h"
 #include "common/utilities.h"
-#include "compiler/translator/AddAndTrueToLoopCondition.h"
 #include "compiler/translator/CallDAG.h"
-#include "compiler/translator/ClampFragDepth.h"
-#include "compiler/translator/ClampPointSize.h"
 #include "compiler/translator/CollectVariables.h"
-#include "compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.h"
-#include "compiler/translator/DeferGlobalInitializers.h"
-#include "compiler/translator/EmulateGLFragColorBroadcast.h"
-#include "compiler/translator/EmulatePrecision.h"
-#include "compiler/translator/FoldExpressions.h"
 #include "compiler/translator/Initialize.h"
-#include "compiler/translator/InitializeVariables.h"
-#include "compiler/translator/IntermNodePatternMatcher.h"
 #include "compiler/translator/IsASTDepthBelowLimit.h"
 #include "compiler/translator/OutputTree.h"
 #include "compiler/translator/ParseContext.h"
-#include "compiler/translator/PruneNoOps.h"
-#include "compiler/translator/RegenerateStructNames.h"
-#include "compiler/translator/RemoveArrayLengthMethod.h"
-#include "compiler/translator/RemoveEmptySwitchStatements.h"
-#include "compiler/translator/RemoveInvariantDeclaration.h"
-#include "compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.h"
-#include "compiler/translator/RemovePow.h"
-#include "compiler/translator/RemoveUnreferencedVariables.h"
-#include "compiler/translator/RewriteDoWhile.h"
-#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h"
-#include "compiler/translator/SeparateDeclarations.h"
-#include "compiler/translator/SimplifyLoopConditions.h"
-#include "compiler/translator/SplitSequenceOperator.h"
-#include "compiler/translator/UnfoldShortCircuitAST.h"
-#include "compiler/translator/UseInterfaceBlockFields.h"
 #include "compiler/translator/ValidateLimitations.h"
 #include "compiler/translator/ValidateMaxParameters.h"
 #include "compiler/translator/ValidateOutputs.h"
 #include "compiler/translator/ValidateVaryingLocations.h"
 #include "compiler/translator/VariablePacker.h"
-#include "compiler/translator/VectorizeVectorScalarArithmetic.h"
+#include "compiler/translator/tree_ops/AddAndTrueToLoopCondition.h"
+#include "compiler/translator/tree_ops/ClampFragDepth.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/EmulatePrecision.h"
+#include "compiler/translator/tree_ops/FoldExpressions.h"
+#include "compiler/translator/tree_ops/InitializeVariables.h"
+#include "compiler/translator/tree_ops/PruneEmptyCases.h"
+#include "compiler/translator/tree_ops/PruneNoOps.h"
+#include "compiler/translator/tree_ops/RegenerateStructNames.h"
+#include "compiler/translator/tree_ops/RemoveArrayLengthMethod.h"
+#include "compiler/translator/tree_ops/RemoveInvariantDeclaration.h"
+#include "compiler/translator/tree_ops/RemovePow.h"
+#include "compiler/translator/tree_ops/RemoveUnreferencedVariables.h"
+#include "compiler/translator/tree_ops/RewriteDoWhile.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/UnfoldShortCircuitAST.h"
+#include "compiler/translator/tree_ops/UseInterfaceBlockFields.h"
+#include "compiler/translator/tree_ops/VectorizeVectorScalarArithmetic.h"
+#include "compiler/translator/tree_util/BuiltIn_autogen.h"
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
 #include "compiler/translator/util.h"
 #include "third_party/compiler/ArrayBoundsClamper.h"
 
 namespace sh
 {
 
 namespace
 {
@@ -188,22 +188,22 @@ class TScopedPoolAllocator
     TPoolAllocator *mAllocator;
 };
 
 class TScopedSymbolTableLevel
 {
   public:
     TScopedSymbolTableLevel(TSymbolTable *table) : mTable(table)
     {
-        ASSERT(mTable->atBuiltInLevel());
+        ASSERT(mTable->isEmpty());
         mTable->push();
     }
     ~TScopedSymbolTableLevel()
     {
-        while (!mTable->atBuiltInLevel())
+        while (!mTable->isEmpty())
             mTable->pop();
     }
 
   private:
     TSymbolTable *mTable;
 };
 
 int MapSpecToShaderVersion(ShShaderSpec spec)
@@ -220,16 +220,61 @@ int MapSpecToShaderVersion(ShShaderSpec 
         case SH_WEBGL3_SPEC:
             return 310;
         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);
 }
 
@@ -446,41 +491,36 @@ bool TCompiler::checkAndSimplifyAST(TInt
     }
 
     if (shouldRunLoopAndIndexingValidation(compileOptions) &&
         !ValidateLimitations(root, shaderType, &symbolTable, &mDiagnostics))
     {
         return false;
     }
 
+    if (!ValidateFragColorAndFragData(shaderType, shaderVersion, symbolTable, &mDiagnostics))
+    {
+        return false;
+    }
+
     // Fold expressions that could not be folded before validation that was done as a part of
     // parsing.
     FoldExpressions(root, &mDiagnostics);
     // Folding should only be able to generate warnings.
     ASSERT(mDiagnostics.numErrors() == 0);
 
     // 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.
     // After this empty declarations are not allowed in the AST.
     PruneNoOps(root, &symbolTable);
 
-    // 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 may have left switch
-    // statements that only contained an empty declaration inside the final case in an invalid
-    // state. Relies on that PruneNoOps has already been run.
-    RemoveNoOpCasesFromEndOfSwitchStatements(root, &symbolTable);
-
-    // Remove empty switch statements - this makes output simpler.
-    RemoveEmptySwitchStatements(root);
-
     // Create the function DAG and check there is no recursion
     if (!initCallDag(root))
     {
         return false;
     }
 
     if ((compileOptions & SH_LIMIT_CALL_STACK_DEPTH) && !checkCallDepth())
     {
@@ -543,17 +583,17 @@ bool TCompiler::checkAndSimplifyAST(TInt
 
     if (compileOptions & SH_UNFOLD_SHORT_CIRCUIT)
     {
         UnfoldShortCircuitAST(root);
     }
 
     if (compileOptions & SH_REMOVE_POW_WITH_CONSTANT_EXPONENT)
     {
-        RemovePow(root);
+        RemovePow(root, &symbolTable);
     }
 
     if (compileOptions & SH_REGENERATE_STRUCT_NAMES)
     {
         RegenerateStructNames gen(&symbolTable);
         root->traverse(&gen);
     }
 
@@ -583,16 +623,24 @@ bool TCompiler::checkAndSimplifyAST(TInt
 
     SplitSequenceOperator(root, IntermNodePatternMatcher::kArrayLengthMethod | simplifyScalarized,
                           &getSymbolTable());
 
     RemoveArrayLengthMethod(root);
 
     RemoveUnreferencedVariables(root, &symbolTable);
 
+    // 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.
+    PruneEmptyCases(root);
+
     // Built-in function emulation needs to happen after validateLimitations pass.
     // TODO(jmadill): Remove global pool allocator.
     GetGlobalPoolAllocator()->lock();
     initBuiltInFunctionEmulator(&builtInFunctionEmulator, compileOptions);
     GetGlobalPoolAllocator()->unlock();
     builtInFunctionEmulator.markBuiltInFunctionsForEmulation(root);
 
     if (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS)
@@ -600,17 +648,17 @@ bool TCompiler::checkAndSimplifyAST(TInt
         ScalarizeVecAndMatConstructorArgs(root, shaderType, fragmentPrecisionHigh, &symbolTable);
     }
 
     if (shouldCollectVariables(compileOptions))
     {
         ASSERT(!variablesCollected);
         CollectVariables(root, &attributes, &outputVariables, &uniforms, &inputVaryings,
                          &outputVaryings, &uniformBlocks, &shaderStorageBlocks, &inBlocks,
-                         hashFunction, &symbolTable, shaderVersion, shaderType, extensionBehavior);
+                         hashFunction, &symbolTable, shaderType, extensionBehavior);
         collectInterfaceBlocks();
         variablesCollected = true;
         if (compileOptions & SH_USE_UNUSED_STANDARD_SHARED_BLOCKS)
         {
             useAllMembersInUnusedStandardAndSharedBlocks(root);
         }
         if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS)
         {
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp
+++ /dev/null
@@ -1,210 +0,0 @@
-//
-// Copyright (c) 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/DeclareAndInitBuiltinsForInstancedMultiview.h"
-
-#include "compiler/translator/FindMain.h"
-#include "compiler/translator/InitializeVariables.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/ReplaceVariable.h"
-#include "compiler/translator/StaticType.h"
-#include "compiler/translator/SymbolTable.h"
-#include "compiler/translator/util.h"
-
-namespace sh
-{
-
-namespace
-{
-
-constexpr const ImmutableString kGlLayerString("gl_Layer");
-constexpr const ImmutableString kGlViewportIndexString("gl_ViewportIndex");
-constexpr const ImmutableString kGlViewIdOVRString("gl_ViewID_OVR");
-constexpr const ImmutableString kGlInstanceIdString("gl_InstanceID");
-constexpr const ImmutableString kViewIDVariableName("ViewID_OVR");
-constexpr const ImmutableString kInstanceIDVariableName("InstanceID");
-constexpr const ImmutableString kMultiviewBaseViewLayerIndexVariableName(
-    "multiviewBaseViewLayerIndex");
-
-TIntermSymbol *CreateGLInstanceIDSymbol(const TSymbolTable &symbolTable)
-{
-    return ReferenceBuiltInVariable(kGlInstanceIdString, symbolTable, 300);
-}
-
-// 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, EbpHigh, EvqConst));
-
-    // Create a uint(gl_InstanceID) node.
-    TIntermSequence *glInstanceIDSymbolCastArguments = new TIntermSequence();
-    glInstanceIDSymbolCastArguments->push_back(CreateGLInstanceIDSymbol(symbolTable));
-    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 = new TIntermSequence();
-    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);
-}
-
-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);
-}
-
-// 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 = new TIntermSequence();
-    viewIDSymbolCastArguments->push_back(new TIntermSymbol(viewID));
-    TIntermAggregate *viewIDAsInt = TIntermAggregate::CreateConstructor(
-        TType(EbtInt, EbpHigh, EvqTemporary), viewIDSymbolCastArguments);
-
-    // Create a gl_ViewportIndex node.
-    TIntermSymbol *viewportIndexSymbol =
-        ReferenceBuiltInVariable(kGlViewportIndexString, symbolTable, 0);
-
-    // 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 = ReferenceBuiltInVariable(kGlLayerString, symbolTable, 0);
-
-    // 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
-
-void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
-                                                 unsigned numberOfViews,
-                                                 GLenum shaderType,
-                                                 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);
-    ReplaceVariable(
-        root,
-        static_cast<const TVariable *>(symbolTable->findBuiltIn(kGlViewIdOVRString, 300, true)),
-        viewID);
-    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);
-        ReplaceVariable(root,
-                        static_cast<const TVariable *>(
-                            symbolTable->findBuiltIn(kGlInstanceIdString, 300, true)),
-                        instanceID);
-
-        TIntermSequence *initializers = new TIntermSequence();
-        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 & SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER) != 0u;
-        // 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);
-    }
-}
-
-}  // namespace sh
\ No newline at end of file
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// Copyright (c) 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 SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER 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_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_
-#define COMPILER_TRANSLATOR_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_
-
-#include "GLSLANG/ShaderLang.h"
-#include "angle_gl.h"
-
-namespace sh
-{
-
-class TIntermBlock;
-class TSymbolTable;
-
-void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
-                                                 unsigned numberOfViews,
-                                                 GLenum shaderType,
-                                                 ShCompileOptions compileOptions,
-                                                 ShShaderOutput shaderOutput,
-                                                 TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_
\ No newline at end of file
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/DeferGlobalInitializers.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-//
-// Copyright (c) 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/DeferGlobalInitializers.h"
-
-#include <vector>
-
-#include "compiler/translator/FindMain.h"
-#include "compiler/translator/InitializeVariables.h"
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/ReplaceVariable.h"
-#include "compiler/translator/StaticType.h"
-#include "compiler/translator/SymbolTable.h"
-
-namespace sh
-{
-
-namespace
-{
-
-constexpr const ImmutableString kInitGlobalsString("initGlobals");
-
-void GetDeferredInitializers(TIntermDeclaration *declaration,
-                             bool initializeUninitializedGlobals,
-                             bool canUseLoopsToInitialize,
-                             bool highPrecisionSupported,
-                             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())
-        {
-            // 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, 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>(), false);
-
-    TIntermFunctionPrototype *initGlobalsFunctionPrototype =
-        CreateInternalFunctionPrototypeNode(*initGlobalsFunction);
-    root->getSequence()->insert(root->getSequence()->begin(), initGlobalsFunctionPrototype);
-    TIntermFunctionDefinition *initGlobalsFunctionDefinition =
-        CreateInternalFunctionDefinitionNode(*initGlobalsFunction, initGlobalsBlock);
-    root->appendStatement(initGlobalsFunctionDefinition);
-
-    TIntermAggregate *initGlobalsCall =
-        TIntermAggregate::CreateFunctionCall(*initGlobalsFunction, new TIntermSequence());
-
-    TIntermBlock *mainBody = FindMainBody(root);
-    mainBody->getSequence()->insert(mainBody->getSequence()->begin(), initGlobalsCall);
-}
-
-}  // namespace
-
-void DeferGlobalInitializers(TIntermBlock *root,
-                             bool initializeUninitializedGlobals,
-                             bool canUseLoopsToInitialize,
-                             bool highPrecisionSupported,
-                             TSymbolTable *symbolTable)
-{
-    TIntermSequence *deferredInitializers = new TIntermSequence();
-    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,
-                                    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());
-        ReplaceVariable(root, var, replacement);
-    }
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/DeferGlobalInitializers.h
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// Copyright (c) 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_DEFERGLOBALINITIALIZERS_H_
-#define COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
-
-namespace sh
-{
-
-class TIntermBlock;
-class TSymbolTable;
-
-void DeferGlobalInitializers(TIntermBlock *root,
-                             bool initializeUninitializedGlobals,
-                             bool canUseLoopsToInitialize,
-                             bool highPrecisionSupported,
-                             TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// 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/EmulateGLFragColorBroadcast.h"
-
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/RunAtTheEndOfShader.h"
-#include "compiler/translator/Symbol.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)
-    {
-    }
-
-    void broadcastGLFragColor(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;
-    }
-}
-
-void GLFragColorBroadcastTraverser::broadcastGLFragColor(TIntermBlock *root)
-{
-    ASSERT(mMaxDrawBuffers > 1);
-    if (!mGLFragColorUsed)
-    {
-        return;
-    }
-
-    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));
-    }
-    RunAtTheEndOfShader(root, broadcastBlock, mSymbolTable);
-}
-
-}  // namespace anonymous
-
-void EmulateGLFragColorBroadcast(TIntermBlock *root,
-                                 int maxDrawBuffers,
-                                 std::vector<sh::OutputVariable> *outputVariables,
-                                 TSymbolTable *symbolTable,
-                                 int shaderVersion)
-{
-    ASSERT(maxDrawBuffers > 1);
-    GLFragColorBroadcastTraverser traverser(maxDrawBuffers, symbolTable, shaderVersion);
-    root->traverse(&traverser);
-    if (traverser.isGLFragColorUsed())
-    {
-        traverser.updateTree();
-        traverser.broadcastGLFragColor(root);
-        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);
-            }
-        }
-    }
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/EmulateGLFragColorBroadcast.h
+++ /dev/null
@@ -1,31 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// Emulate gl_FragColor broadcast behaviors in ES2 where
-// GL_EXT_draw_buffers is explicitly enabled in a fragment shader.
-//
-
-#ifndef COMPILER_TRANSLATOR_EMULATEGLFRAGCOLORBROADCAST_H_
-#define COMPILER_TRANSLATOR_EMULATEGLFRAGCOLORBROADCAST_H_
-
-#include <vector>
-
-namespace sh
-{
-struct OutputVariable;
-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.
-void EmulateGLFragColorBroadcast(TIntermBlock *root,
-                                 int maxDrawBuffers,
-                                 std::vector<OutputVariable> *outputVariables,
-                                 TSymbolTable *symbolTable,
-                                 int shaderVersion);
-}
-
-#endif  // COMPILER_TRANSLATOR_EMULATEGLFRAGCOLORBROADCAST_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/EmulatePrecision.cpp
+++ /dev/null
@@ -1,779 +0,0 @@
-//
-// Copyright (c) 2002-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/EmulatePrecision.h"
-
-#include "compiler/translator/FunctionLookup.h"
-
-#include <memory>
-
-namespace sh
-{
-
-namespace
-{
-
-constexpr const ImmutableString kParamXName("x");
-constexpr const ImmutableString kParamYName("y");
-constexpr const ImmutableString kAngleFrmString("angle_frm");
-constexpr const ImmutableString kAngleFrlString("angle_frl");
-
-class RoundingHelperWriter : angle::NonCopyable
-{
-  public:
-    static RoundingHelperWriter *createHelperWriter(const ShShaderOutput outputLanguage);
-
-    void writeCommonRoundingHelpers(TInfoSinkBase &sink, const int shaderVersion);
-    void writeCompoundAssignmentHelper(TInfoSinkBase &sink,
-                                       const char *lType,
-                                       const char *rType,
-                                       const char *opStr,
-                                       const char *opNameStr);
-
-    virtual ~RoundingHelperWriter() {}
-
-  protected:
-    RoundingHelperWriter(const ShShaderOutput outputLanguage) : mOutputLanguage(outputLanguage) {}
-    RoundingHelperWriter() = delete;
-
-    const ShShaderOutput mOutputLanguage;
-
-  private:
-    virtual std::string getTypeString(const char *glslType)     = 0;
-    virtual void writeFloatRoundingHelpers(TInfoSinkBase &sink) = 0;
-    virtual void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) = 0;
-    virtual void writeMatrixRoundingHelper(TInfoSinkBase &sink,
-                                           const unsigned int columns,
-                                           const unsigned int rows,
-                                           const char *functionName) = 0;
-};
-
-class RoundingHelperWriterGLSL : public RoundingHelperWriter
-{
-  public:
-    RoundingHelperWriterGLSL(const ShShaderOutput outputLanguage)
-        : RoundingHelperWriter(outputLanguage)
-    {
-    }
-
-  private:
-    std::string getTypeString(const char *glslType) override;
-    void writeFloatRoundingHelpers(TInfoSinkBase &sink) override;
-    void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) override;
-    void writeMatrixRoundingHelper(TInfoSinkBase &sink,
-                                   const unsigned int columns,
-                                   const unsigned int rows,
-                                   const char *functionName) override;
-};
-
-class RoundingHelperWriterESSL : public RoundingHelperWriterGLSL
-{
-  public:
-    RoundingHelperWriterESSL(const ShShaderOutput outputLanguage)
-        : RoundingHelperWriterGLSL(outputLanguage)
-    {
-    }
-
-  private:
-    std::string getTypeString(const char *glslType) override;
-};
-
-class RoundingHelperWriterHLSL : public RoundingHelperWriter
-{
-  public:
-    RoundingHelperWriterHLSL(const ShShaderOutput outputLanguage)
-        : RoundingHelperWriter(outputLanguage)
-    {
-    }
-
-  private:
-    std::string getTypeString(const char *glslType) override;
-    void writeFloatRoundingHelpers(TInfoSinkBase &sink) override;
-    void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) override;
-    void writeMatrixRoundingHelper(TInfoSinkBase &sink,
-                                   const unsigned int columns,
-                                   const unsigned int rows,
-                                   const char *functionName) override;
-};
-
-RoundingHelperWriter *RoundingHelperWriter::createHelperWriter(const ShShaderOutput outputLanguage)
-{
-    ASSERT(EmulatePrecision::SupportedInLanguage(outputLanguage));
-    switch (outputLanguage)
-    {
-        case SH_HLSL_4_1_OUTPUT:
-            return new RoundingHelperWriterHLSL(outputLanguage);
-        case SH_ESSL_OUTPUT:
-            return new RoundingHelperWriterESSL(outputLanguage);
-        default:
-            return new RoundingHelperWriterGLSL(outputLanguage);
-    }
-}
-
-void RoundingHelperWriter::writeCommonRoundingHelpers(TInfoSinkBase &sink, const int shaderVersion)
-{
-    // Write the angle_frm functions that round floating point numbers to
-    // half precision, and angle_frl functions that round them to minimum lowp
-    // precision.
-
-    writeFloatRoundingHelpers(sink);
-    writeVectorRoundingHelpers(sink, 2);
-    writeVectorRoundingHelpers(sink, 3);
-    writeVectorRoundingHelpers(sink, 4);
-    if (shaderVersion > 100)
-    {
-        for (unsigned int columns = 2; columns <= 4; ++columns)
-        {
-            for (unsigned int rows = 2; rows <= 4; ++rows)
-            {
-                writeMatrixRoundingHelper(sink, columns, rows, "angle_frm");
-                writeMatrixRoundingHelper(sink, columns, rows, "angle_frl");
-            }
-        }
-    }
-    else
-    {
-        for (unsigned int size = 2; size <= 4; ++size)
-        {
-            writeMatrixRoundingHelper(sink, size, size, "angle_frm");
-            writeMatrixRoundingHelper(sink, size, size, "angle_frl");
-        }
-    }
-}
-
-void RoundingHelperWriter::writeCompoundAssignmentHelper(TInfoSinkBase &sink,
-                                                         const char *lType,
-                                                         const char *rType,
-                                                         const char *opStr,
-                                                         const char *opNameStr)
-{
-    std::string lTypeStr = getTypeString(lType);
-    std::string rTypeStr = getTypeString(rType);
-
-    // Note that y should be passed through angle_frm at the function call site,
-    // but x can't be passed through angle_frm there since it is an inout parameter.
-    // So only pass x and the result through angle_frm here.
-    // clang-format off
-    sink <<
-        lTypeStr << " angle_compound_" << opNameStr << "_frm(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n"
-        "    x = angle_frm(angle_frm(x) " << opStr << " y);\n"
-        "    return x;\n"
-        "}\n";
-    sink <<
-        lTypeStr << " angle_compound_" << opNameStr << "_frl(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n"
-        "    x = angle_frl(angle_frl(x) " << opStr << " y);\n"
-        "    return x;\n"
-        "}\n";
-    // clang-format on
-}
-
-std::string RoundingHelperWriterGLSL::getTypeString(const char *glslType)
-{
-    return glslType;
-}
-
-std::string RoundingHelperWriterESSL::getTypeString(const char *glslType)
-{
-    std::stringstream typeStrStr;
-    typeStrStr << "highp " << glslType;
-    return typeStrStr.str();
-}
-
-void RoundingHelperWriterGLSL::writeFloatRoundingHelpers(TInfoSinkBase &sink)
-{
-    // Unoptimized version of angle_frm for single floats:
-    //
-    // int webgl_maxNormalExponent(in int exponentBits)
-    // {
-    //     int possibleExponents = int(exp2(float(exponentBits)));
-    //     int exponentBias = possibleExponents / 2 - 1;
-    //     int allExponentBitsOne = possibleExponents - 1;
-    //     return (allExponentBitsOne - 1) - exponentBias;
-    // }
-    //
-    // float angle_frm(in float x)
-    // {
-    //     int mantissaBits = 10;
-    //     int exponentBits = 5;
-    //     float possibleMantissas = exp2(float(mantissaBits));
-    //     float mantissaMax = 2.0 - 1.0 / possibleMantissas;
-    //     int maxNE = webgl_maxNormalExponent(exponentBits);
-    //     float max = exp2(float(maxNE)) * mantissaMax;
-    //     if (x > max)
-    //     {
-    //         return max;
-    //     }
-    //     if (x < -max)
-    //     {
-    //         return -max;
-    //     }
-    //     float exponent = floor(log2(abs(x)));
-    //     if (abs(x) == 0.0 || exponent < -float(maxNE))
-    //     {
-    //         return 0.0 * sign(x)
-    //     }
-    //     x = x * exp2(-(exponent - float(mantissaBits)));
-    //     x = sign(x) * floor(abs(x));
-    //     return x * exp2(exponent - float(mantissaBits));
-    // }
-
-    // All numbers with a magnitude less than 2^-15 are subnormal, and are
-    // flushed to zero.
-
-    // Note the constant numbers below:
-    // a) 65504 is the maximum possible mantissa (1.1111111111 in binary) times
-    //    2^15, the maximum normal exponent.
-    // b) 10.0 is the number of mantissa bits.
-    // c) -25.0 is the minimum normal half-float exponent -15.0 minus the number
-    //    of mantissa bits.
-    // d) + 1e-30 is to make sure the argument of log2() won't be zero. It can
-    //    only affect the result of log2 on x where abs(x) < 1e-22. Since these
-    //    numbers will be flushed to zero either way (2^-15 is the smallest
-    //    normal positive number), this does not introduce any error.
-
-    std::string floatType = getTypeString("float");
-
-    // clang-format off
-    sink <<
-        floatType << " angle_frm(in " << floatType << " x) {\n"
-        "    x = clamp(x, -65504.0, 65504.0);\n"
-        "    " << floatType << " exponent = floor(log2(abs(x) + 1e-30)) - 10.0;\n"
-        "    bool isNonZero = (exponent >= -25.0);\n"
-        "    x = x * exp2(-exponent);\n"
-        "    x = sign(x) * floor(abs(x));\n"
-        "    return x * exp2(exponent) * float(isNonZero);\n"
-        "}\n";
-
-    sink <<
-        floatType << " angle_frl(in " << floatType << " x) {\n"
-        "    x = clamp(x, -2.0, 2.0);\n"
-        "    x = x * 256.0;\n"
-        "    x = sign(x) * floor(abs(x));\n"
-        "    return x * 0.00390625;\n"
-        "}\n";
-    // clang-format on
-}
-
-void RoundingHelperWriterGLSL::writeVectorRoundingHelpers(TInfoSinkBase &sink,
-                                                          const unsigned int size)
-{
-    std::stringstream vecTypeStrStr;
-    vecTypeStrStr << "vec" << size;
-    std::string vecType = getTypeString(vecTypeStrStr.str().c_str());
-
-    // clang-format off
-    sink <<
-        vecType << " angle_frm(in " << vecType << " v) {\n"
-        "    v = clamp(v, -65504.0, 65504.0);\n"
-        "    " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n"
-        "    bvec" << size << " isNonZero = greaterThanEqual(exponent, vec" << size << "(-25.0));\n"
-        "    v = v * exp2(-exponent);\n"
-        "    v = sign(v) * floor(abs(v));\n"
-        "    return v * exp2(exponent) * vec" << size << "(isNonZero);\n"
-        "}\n";
-
-    sink <<
-        vecType << " angle_frl(in " << vecType << " v) {\n"
-        "    v = clamp(v, -2.0, 2.0);\n"
-        "    v = v * 256.0;\n"
-        "    v = sign(v) * floor(abs(v));\n"
-        "    return v * 0.00390625;\n"
-        "}\n";
-    // clang-format on
-}
-
-void RoundingHelperWriterGLSL::writeMatrixRoundingHelper(TInfoSinkBase &sink,
-                                                         const unsigned int columns,
-                                                         const unsigned int rows,
-                                                         const char *functionName)
-{
-    std::stringstream matTypeStrStr;
-    matTypeStrStr << "mat" << columns;
-    if (rows != columns)
-    {
-        matTypeStrStr << "x" << rows;
-    }
-    std::string matType = getTypeString(matTypeStrStr.str().c_str());
-
-    sink << matType << " " << functionName << "(in " << matType << " m) {\n"
-         << "    " << matType << " rounded;\n";
-
-    for (unsigned int i = 0; i < columns; ++i)
-    {
-        sink << "    rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n";
-    }
-
-    sink << "    return rounded;\n"
-            "}\n";
-}
-
-static const char *GetHLSLTypeStr(const char *floatTypeStr)
-{
-    if (strcmp(floatTypeStr, "float") == 0)
-    {
-        return "float";
-    }
-    if (strcmp(floatTypeStr, "vec2") == 0)
-    {
-        return "float2";
-    }
-    if (strcmp(floatTypeStr, "vec3") == 0)
-    {
-        return "float3";
-    }
-    if (strcmp(floatTypeStr, "vec4") == 0)
-    {
-        return "float4";
-    }
-    if (strcmp(floatTypeStr, "mat2") == 0)
-    {
-        return "float2x2";
-    }
-    if (strcmp(floatTypeStr, "mat3") == 0)
-    {
-        return "float3x3";
-    }
-    if (strcmp(floatTypeStr, "mat4") == 0)
-    {
-        return "float4x4";
-    }
-    if (strcmp(floatTypeStr, "mat2x3") == 0)
-    {
-        return "float2x3";
-    }
-    if (strcmp(floatTypeStr, "mat2x4") == 0)
-    {
-        return "float2x4";
-    }
-    if (strcmp(floatTypeStr, "mat3x2") == 0)
-    {
-        return "float3x2";
-    }
-    if (strcmp(floatTypeStr, "mat3x4") == 0)
-    {
-        return "float3x4";
-    }
-    if (strcmp(floatTypeStr, "mat4x2") == 0)
-    {
-        return "float4x2";
-    }
-    if (strcmp(floatTypeStr, "mat4x3") == 0)
-    {
-        return "float4x3";
-    }
-    UNREACHABLE();
-    return nullptr;
-}
-
-std::string RoundingHelperWriterHLSL::getTypeString(const char *glslType)
-{
-    return GetHLSLTypeStr(glslType);
-}
-
-void RoundingHelperWriterHLSL::writeFloatRoundingHelpers(TInfoSinkBase &sink)
-{
-    // In HLSL scalars are the same as 1-vectors.
-    writeVectorRoundingHelpers(sink, 1);
-}
-
-void RoundingHelperWriterHLSL::writeVectorRoundingHelpers(TInfoSinkBase &sink,
-                                                          const unsigned int size)
-{
-    std::stringstream vecTypeStrStr;
-    vecTypeStrStr << "float" << size;
-    std::string vecType = vecTypeStrStr.str();
-
-    // clang-format off
-    sink <<
-        vecType << " angle_frm(" << vecType << " v) {\n"
-        "    v = clamp(v, -65504.0, 65504.0);\n"
-        "    " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n"
-        "    bool" << size << " isNonZero = exponent < -25.0;\n"
-        "    v = v * exp2(-exponent);\n"
-        "    v = sign(v) * floor(abs(v));\n"
-        "    return v * exp2(exponent) * (float" << size << ")(isNonZero);\n"
-        "}\n";
-
-    sink <<
-        vecType << " angle_frl(" << vecType << " v) {\n"
-        "    v = clamp(v, -2.0, 2.0);\n"
-        "    v = v * 256.0;\n"
-        "    v = sign(v) * floor(abs(v));\n"
-        "    return v * 0.00390625;\n"
-        "}\n";
-    // clang-format on
-}
-
-void RoundingHelperWriterHLSL::writeMatrixRoundingHelper(TInfoSinkBase &sink,
-                                                         const unsigned int columns,
-                                                         const unsigned int rows,
-                                                         const char *functionName)
-{
-    std::stringstream matTypeStrStr;
-    matTypeStrStr << "float" << columns << "x" << rows;
-    std::string matType = matTypeStrStr.str();
-
-    sink << matType << " " << functionName << "(" << matType << " m) {\n"
-         << "    " << matType << " rounded;\n";
-
-    for (unsigned int i = 0; i < columns; ++i)
-    {
-        sink << "    rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n";
-    }
-
-    sink << "    return rounded;\n"
-            "}\n";
-}
-
-bool canRoundFloat(const TType &type)
-{
-    return type.getBasicType() == EbtFloat && !type.isArray() &&
-           (type.getPrecision() == EbpLow || type.getPrecision() == EbpMedium);
-}
-
-bool ParentUsesResult(TIntermNode *parent, TIntermTyped *node)
-{
-    if (!parent)
-    {
-        return false;
-    }
-
-    TIntermBlock *blockParent = parent->getAsBlock();
-    // If the parent is a block, the result is not assigned anywhere,
-    // so rounding it is not needed. In particular, this can avoid a lot of
-    // unnecessary rounding of unused return values of assignment.
-    if (blockParent)
-    {
-        return false;
-    }
-    TIntermBinary *binaryParent = parent->getAsBinaryNode();
-    if (binaryParent && binaryParent->getOp() == EOpComma && (binaryParent->getRight() != node))
-    {
-        return false;
-    }
-    return true;
-}
-
-bool ParentConstructorTakesCareOfRounding(TIntermNode *parent, TIntermTyped *node)
-{
-    if (!parent)
-    {
-        return false;
-    }
-    TIntermAggregate *parentConstructor = parent->getAsAggregate();
-    if (!parentConstructor || parentConstructor->getOp() != EOpConstruct)
-    {
-        return false;
-    }
-    if (parentConstructor->getPrecision() != node->getPrecision())
-    {
-        return false;
-    }
-    return canRoundFloat(parentConstructor->getType());
-}
-
-}  // namespace anonymous
-
-EmulatePrecision::EmulatePrecision(TSymbolTable *symbolTable)
-    : TLValueTrackingTraverser(true, true, true, symbolTable), mDeclaringVariables(false)
-{
-}
-
-void EmulatePrecision::visitSymbol(TIntermSymbol *node)
-{
-    TIntermNode *parent = getParentNode();
-    if (canRoundFloat(node->getType()) && ParentUsesResult(parent, node) &&
-        !ParentConstructorTakesCareOfRounding(parent, node) && !mDeclaringVariables &&
-        !isLValueRequiredHere())
-    {
-        TIntermNode *replacement = createRoundingFunctionCallNode(node);
-        queueReplacement(replacement, OriginalNode::BECOMES_CHILD);
-    }
-}
-
-bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node)
-{
-    bool visitChildren = true;
-
-    TOperator op = node->getOp();
-
-    // RHS of initialize is not being declared.
-    if (op == EOpInitialize && visit == InVisit)
-        mDeclaringVariables = false;
-
-    if ((op == EOpIndexDirectStruct) && visit == InVisit)
-        visitChildren = false;
-
-    if (visit != PreVisit)
-        return visitChildren;
-
-    const TType &type = node->getType();
-    bool roundFloat   = canRoundFloat(type);
-
-    if (roundFloat)
-    {
-        switch (op)
-        {
-            // Math operators that can result in a float may need to apply rounding to the return
-            // value. Note that in the case of assignment, the rounding is applied to its return
-            // value here, not the value being assigned.
-            case EOpAssign:
-            case EOpAdd:
-            case EOpSub:
-            case EOpMul:
-            case EOpDiv:
-            case EOpVectorTimesScalar:
-            case EOpVectorTimesMatrix:
-            case EOpMatrixTimesVector:
-            case EOpMatrixTimesScalar:
-            case EOpMatrixTimesMatrix:
-            {
-                TIntermNode *parent = getParentNode();
-                if (!ParentUsesResult(parent, node) ||
-                    ParentConstructorTakesCareOfRounding(parent, node))
-                {
-                    break;
-                }
-                TIntermNode *replacement = createRoundingFunctionCallNode(node);
-                queueReplacement(replacement, OriginalNode::BECOMES_CHILD);
-                break;
-            }
-
-            // Compound assignment cases need to replace the operator with a function call.
-            case EOpAddAssign:
-            {
-                mEmulateCompoundAdd.insert(
-                    TypePair(type.getBuiltInTypeNameString(),
-                             node->getRight()->getType().getBuiltInTypeNameString()));
-                TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(
-                    node->getLeft(), node->getRight(), "add");
-                queueReplacement(replacement, OriginalNode::IS_DROPPED);
-                break;
-            }
-            case EOpSubAssign:
-            {
-                mEmulateCompoundSub.insert(
-                    TypePair(type.getBuiltInTypeNameString(),
-                             node->getRight()->getType().getBuiltInTypeNameString()));
-                TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(
-                    node->getLeft(), node->getRight(), "sub");
-                queueReplacement(replacement, OriginalNode::IS_DROPPED);
-                break;
-            }
-            case EOpMulAssign:
-            case EOpVectorTimesMatrixAssign:
-            case EOpVectorTimesScalarAssign:
-            case EOpMatrixTimesScalarAssign:
-            case EOpMatrixTimesMatrixAssign:
-            {
-                mEmulateCompoundMul.insert(
-                    TypePair(type.getBuiltInTypeNameString(),
-                             node->getRight()->getType().getBuiltInTypeNameString()));
-                TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(
-                    node->getLeft(), node->getRight(), "mul");
-                queueReplacement(replacement, OriginalNode::IS_DROPPED);
-                break;
-            }
-            case EOpDivAssign:
-            {
-                mEmulateCompoundDiv.insert(
-                    TypePair(type.getBuiltInTypeNameString(),
-                             node->getRight()->getType().getBuiltInTypeNameString()));
-                TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(
-                    node->getLeft(), node->getRight(), "div");
-                queueReplacement(replacement, OriginalNode::IS_DROPPED);
-                break;
-            }
-            default:
-                // The rest of the binary operations should not need precision emulation.
-                break;
-        }
-    }
-    return visitChildren;
-}
-
-bool EmulatePrecision::visitDeclaration(Visit visit, TIntermDeclaration *node)
-{
-    // Variable or interface block declaration.
-    if (visit == PreVisit)
-    {
-        mDeclaringVariables = true;
-    }
-    else if (visit == InVisit)
-    {
-        mDeclaringVariables = true;
-    }
-    else
-    {
-        mDeclaringVariables = false;
-    }
-    return true;
-}
-
-bool EmulatePrecision::visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node)
-{
-    return false;
-}
-
-bool EmulatePrecision::visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node)
-{
-    return false;
-}
-
-bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node)
-{
-    if (visit != PreVisit)
-        return true;
-
-    // User-defined function return values are not rounded. The calculations that produced
-    // the value inside the function definition should have been rounded.
-    TOperator op = node->getOp();
-    if (op == EOpCallInternalRawFunction || op == EOpCallFunctionInAST ||
-        (op == EOpConstruct && node->getBasicType() == EbtStruct))
-    {
-        return true;
-    }
-
-    TIntermNode *parent = getParentNode();
-    if (canRoundFloat(node->getType()) && ParentUsesResult(parent, node) &&
-        !ParentConstructorTakesCareOfRounding(parent, node))
-    {
-        TIntermNode *replacement = createRoundingFunctionCallNode(node);
-        queueReplacement(replacement, OriginalNode::BECOMES_CHILD);
-    }
-    return true;
-}
-
-bool EmulatePrecision::visitUnary(Visit visit, TIntermUnary *node)
-{
-    switch (node->getOp())
-    {
-        case EOpNegative:
-        case EOpLogicalNot:
-        case EOpPostIncrement:
-        case EOpPostDecrement:
-        case EOpPreIncrement:
-        case EOpPreDecrement:
-        case EOpLogicalNotComponentWise:
-            break;
-        default:
-            if (canRoundFloat(node->getType()) && visit == PreVisit)
-            {
-                TIntermNode *replacement = createRoundingFunctionCallNode(node);
-                queueReplacement(replacement, OriginalNode::BECOMES_CHILD);
-            }
-            break;
-    }
-
-    return true;
-}
-
-void EmulatePrecision::writeEmulationHelpers(TInfoSinkBase &sink,
-                                             const int shaderVersion,
-                                             const ShShaderOutput outputLanguage)
-{
-    std::unique_ptr<RoundingHelperWriter> roundingHelperWriter(
-        RoundingHelperWriter::createHelperWriter(outputLanguage));
-
-    roundingHelperWriter->writeCommonRoundingHelpers(sink, shaderVersion);
-
-    EmulationSet::const_iterator it;
-    for (it = mEmulateCompoundAdd.begin(); it != mEmulateCompoundAdd.end(); it++)
-        roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "+", "add");
-    for (it = mEmulateCompoundSub.begin(); it != mEmulateCompoundSub.end(); it++)
-        roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "-", "sub");
-    for (it = mEmulateCompoundDiv.begin(); it != mEmulateCompoundDiv.end(); it++)
-        roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "/", "div");
-    for (it = mEmulateCompoundMul.begin(); it != mEmulateCompoundMul.end(); it++)
-        roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "*", "mul");
-}
-
-// static
-bool EmulatePrecision::SupportedInLanguage(const ShShaderOutput outputLanguage)
-{
-    switch (outputLanguage)
-    {
-        case SH_HLSL_4_1_OUTPUT:
-        case SH_ESSL_OUTPUT:
-            return true;
-        default:
-            // Other languages not yet supported
-            return (outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT ||
-                    sh::IsGLSL130OrNewer(outputLanguage));
-    }
-}
-
-const TFunction *EmulatePrecision::getInternalFunction(const ImmutableString &functionName,
-                                                       const TType &returnType,
-                                                       TIntermSequence *arguments,
-                                                       const TVector<TConstParameter> &parameters,
-                                                       bool knownToNotHaveSideEffects)
-{
-    ImmutableString mangledName = TFunctionLookup::GetMangledName(functionName.data(), *arguments);
-    if (mInternalFunctions.find(mangledName) == mInternalFunctions.end())
-    {
-        TFunction *func = new TFunction(mSymbolTable, functionName, SymbolType::AngleInternal,
-                                        new TType(returnType), knownToNotHaveSideEffects);
-        ASSERT(parameters.size() == arguments->size());
-        for (size_t i = 0; i < parameters.size(); ++i)
-        {
-            func->addParameter(parameters[i]);
-        }
-        mInternalFunctions[mangledName] = func;
-    }
-    return mInternalFunctions[mangledName];
-}
-
-TIntermAggregate *EmulatePrecision::createRoundingFunctionCallNode(TIntermTyped *roundedChild)
-{
-    const ImmutableString *roundFunctionName = &kAngleFrmString;
-    if (roundedChild->getPrecision() == EbpLow)
-        roundFunctionName = &kAngleFrlString;
-    TIntermSequence *arguments = new TIntermSequence();
-    arguments->push_back(roundedChild);
-
-    TVector<TConstParameter> parameters;
-    TType *paramType = new TType(roundedChild->getType());
-    paramType->setPrecision(EbpHigh);
-    paramType->setQualifier(EvqIn);
-    parameters.push_back(TConstParameter(kParamXName, static_cast<const TType *>(paramType)));
-
-    return TIntermAggregate::CreateRawFunctionCall(
-        *getInternalFunction(*roundFunctionName, roundedChild->getType(), arguments, parameters,
-                             true),
-        arguments);
-}
-
-TIntermAggregate *EmulatePrecision::createCompoundAssignmentFunctionCallNode(TIntermTyped *left,
-                                                                             TIntermTyped *right,
-                                                                             const char *opNameStr)
-{
-    std::stringstream strstr;
-    if (left->getPrecision() == EbpMedium)
-        strstr << "angle_compound_" << opNameStr << "_frm";
-    else
-        strstr << "angle_compound_" << opNameStr << "_frl";
-    ImmutableString functionName = ImmutableString(strstr.str());
-    TIntermSequence *arguments = new TIntermSequence();
-    arguments->push_back(left);
-    arguments->push_back(right);
-
-    TVector<TConstParameter> parameters;
-    TType *leftParamType = new TType(left->getType());
-    leftParamType->setPrecision(EbpHigh);
-    leftParamType->setQualifier(EvqOut);
-    parameters.push_back(TConstParameter(kParamXName, static_cast<const TType *>(leftParamType)));
-    TType *rightParamType = new TType(right->getType());
-    rightParamType->setPrecision(EbpHigh);
-    rightParamType->setQualifier(EvqIn);
-    parameters.push_back(TConstParameter(kParamYName, static_cast<const TType *>(rightParamType)));
-
-    return TIntermAggregate::CreateRawFunctionCall(
-        *getInternalFunction(functionName, left->getType(), arguments, parameters, false),
-        arguments);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/EmulatePrecision.h
+++ /dev/null
@@ -1,86 +0,0 @@
-//
-// Copyright (c) 2002-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_EMULATE_PRECISION_H_
-#define COMPILER_TRANSLATOR_EMULATE_PRECISION_H_
-
-#include "GLSLANG/ShaderLang.h"
-#include "common/angleutils.h"
-#include "compiler/translator/Compiler.h"
-#include "compiler/translator/InfoSink.h"
-#include "compiler/translator/IntermTraverse.h"
-
-// This class gathers all compound assignments from the AST and can then write
-// the functions required for their precision emulation. This way there is no
-// need to write a huge number of variations of the emulated compound assignment
-// to every translated shader with emulation enabled.
-
-namespace sh
-{
-
-class EmulatePrecision : public TLValueTrackingTraverser
-{
-  public:
-    EmulatePrecision(TSymbolTable *symbolTable);
-
-    void visitSymbol(TIntermSymbol *node) override;
-    bool visitBinary(Visit visit, TIntermBinary *node) override;
-    bool visitUnary(Visit visit, TIntermUnary *node) override;
-    bool visitAggregate(Visit visit, TIntermAggregate *node) override;
-    bool visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node) override;
-    bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
-    bool visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node) override;
-
-    void writeEmulationHelpers(TInfoSinkBase &sink,
-                               const int shaderVersion,
-                               const ShShaderOutput outputLanguage);
-
-    static bool SupportedInLanguage(const ShShaderOutput outputLanguage);
-
-  private:
-    struct TypePair
-    {
-        TypePair(const char *l, const char *r) : lType(l), rType(r) {}
-
-        const char *lType;
-        const char *rType;
-    };
-
-    struct TypePairComparator
-    {
-        bool operator()(const TypePair &l, const TypePair &r) const
-        {
-            if (l.lType == r.lType)
-                return l.rType < r.rType;
-            return l.lType < r.lType;
-        }
-    };
-
-    const TFunction *getInternalFunction(const ImmutableString &functionName,
-                                         const TType &returnType,
-                                         TIntermSequence *arguments,
-                                         const TVector<TConstParameter> &parameters,
-                                         bool knownToNotHaveSideEffects);
-    TIntermAggregate *createRoundingFunctionCallNode(TIntermTyped *roundedChild);
-    TIntermAggregate *createCompoundAssignmentFunctionCallNode(TIntermTyped *left,
-                                                               TIntermTyped *right,
-                                                               const char *opNameStr);
-
-    typedef std::set<TypePair, TypePairComparator> EmulationSet;
-    EmulationSet mEmulateCompoundAdd;
-    EmulationSet mEmulateCompoundSub;
-    EmulationSet mEmulateCompoundMul;
-    EmulationSet mEmulateCompoundDiv;
-
-    // Map from mangled name to function.
-    TMap<ImmutableString, const TFunction *> mInternalFunctions;
-
-    bool mDeclaringVariables;
-};
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_EMULATE_PRECISION_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ExpandIntegerPowExpressions.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-//
-// Copyright (c) 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/ExpandIntegerPowExpressions.h"
-
-#include <cmath>
-#include <cstdlib>
-
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class Traverser : public TIntermTraverser
-{
-  public:
-    static void Apply(TIntermNode *root, TSymbolTable *symbolTable);
-
-  private:
-    Traverser(TSymbolTable *symbolTable);
-    bool visitAggregate(Visit visit, TIntermAggregate *node) override;
-    void nextIteration();
-
-    bool mFound = false;
-};
-
-// static
-void Traverser::Apply(TIntermNode *root, TSymbolTable *symbolTable)
-{
-    Traverser traverser(symbolTable);
-    do
-    {
-        traverser.nextIteration();
-        root->traverse(&traverser);
-        if (traverser.mFound)
-        {
-            traverser.updateTree();
-        }
-    } while (traverser.mFound);
-}
-
-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;
-    }
-
-    ASSERT(constantExponent->getBasicType() == EbtFloat);
-    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
-
-void ExpandIntegerPowExpressions(TIntermNode *root, TSymbolTable *symbolTable)
-{
-    Traverser::Apply(root, symbolTable);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ExpandIntegerPowExpressions.h
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Copyright (c) 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_EXPANDINTEGERPOWEXPRESSIONS_H_
-#define COMPILER_TRANSLATOR_EXPANDINTEGERPOWEXPRESSIONS_H_
-
-namespace sh
-{
-
-class TIntermNode;
-class TSymbolTable;
-
-void ExpandIntegerPowExpressions(TIntermNode *root, TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_EXPANDINTEGERPOWEXPRESSIONS_H_
--- a/gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.h
+++ b/gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.h
@@ -7,17 +7,17 @@
 // shaders.
 
 #ifndef COMPILER_TRANSLATOR_EXTENSIONGLSL_H_
 #define COMPILER_TRANSLATOR_EXTENSIONGLSL_H_
 
 #include <set>
 #include <string>
 
-#include "compiler/translator/IntermTraverse.h"
+#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
 {
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/FindMain.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-//
-// Copyright (c) 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/FindMain.h"
-
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/Symbol.h"
-
-namespace sh
-{
-
-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
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/FindMain.h
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright (c) 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_FINDMAIN_H_
-#define COMPILER_TRANSLATOR_FINDMAIN_H_
-
-namespace sh
-{
-
-class TIntermBlock;
-class TIntermFunctionDefinition;
-
-TIntermFunctionDefinition *FindMain(TIntermBlock *root);
-TIntermBlock *FindMainBody(TIntermBlock *root);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_FINDMAIN_H_
\ No newline at end of file
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/FindSymbolNode.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-//
-// Copyright (c) 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/FindSymbolNode.h"
-
-#include "compiler/translator/ImmutableString.h"
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/Symbol.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)
-    {
-        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
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/FindSymbolNode.h
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright (c) 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_FIND_SYMBOL_H_
-#define COMPILER_TRANSLATOR_FIND_SYMBOL_H_
-
-namespace sh
-{
-
-class ImmutableString;
-class TIntermNode;
-class TIntermSymbol;
-
-const TIntermSymbol *FindSymbolNode(TIntermNode *root, const ImmutableString &symbolName);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_FIND_SYMBOL_H_
\ No newline at end of file
--- a/gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.cpp
@@ -3,18 +3,18 @@
 // 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/IntermTraverse.h"
 #include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
 
 namespace sh
 {
 
 namespace
 {
 
 class FlagStd140StructsTraverser : public TIntermTraverser
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/FoldExpressions.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-//
-// Copyright (c) 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/FoldExpressions.h"
-
-#include "compiler/translator/Diagnostics.h"
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/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
-
-void FoldExpressions(TIntermBlock *root, TDiagnostics *diagnostics)
-{
-    FoldExpressionsTraverser traverser(diagnostics);
-    do
-    {
-        traverser.nextIteration();
-        root->traverse(&traverser);
-        traverser.updateTree();
-    } while (traverser.didReplace());
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/FoldExpressions.h
+++ /dev/null
@@ -1,24 +0,0 @@
-//
-// Copyright (c) 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_FOLDEXPRESSIONS_H_
-#define COMPILER_TRANSLATOR_FOLDEXPRESSIONS_H_
-
-namespace sh
-{
-
-class TIntermBlock;
-class TDiagnostics;
-
-void FoldExpressions(TIntermBlock *root, TDiagnostics *diagnostics);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_FOLDEXPRESSIONS_H_
--- a/gfx/angle/checkout/src/compiler/translator/ImmutableString.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/ImmutableString.cpp
@@ -30,22 +30,40 @@ const size_t ImmutableString::FowlerNoll
 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::hash32() const
+uint32_t ImmutableString::mangledNameHash() const
 {
-    const char *data_ptr = data();
-    uint32_t hash        = static_cast<uint32_t>(FowlerNollVoHash<4>::kFnvOffsetBasis);
-    while ((*data_ptr) != '\0')
+    const char *dataPtr              = data();
+    uint32_t hash                    = static_cast<uint32_t>(FowlerNollVoHash<4>::kFnvOffsetBasis);
+    const uint32_t kMaxSixBitValue   = (1u << 6) - 1u;
+    uint32_t parenLocation           = kMaxSixBitValue;
+    uint32_t hasArrayOrBlockParamBit = 0u;
+    uint32_t index                   = 0;
+    while (dataPtr[index] != '\0')
     {
-        hash = hash ^ (*data_ptr);
+        hash = hash ^ dataPtr[index];
         hash = hash * static_cast<uint32_t>(FowlerNollVoHash<4>::kFnvPrime);
-        ++data_ptr;
+        if (dataPtr[index] == '(')
+        {
+            // We should only reach here once, since this function should not be called with invalid
+            // mangled names.
+            ASSERT(parenLocation == kMaxSixBitValue);
+            parenLocation = index;
+        }
+        else if (dataPtr[index] == '{' || dataPtr[index] == '[')
+        {
+            hasArrayOrBlockParamBit = 1u;
+        }
+        ++index;
     }
-    return hash;
+    // Should not be called with strings longer than 63 characters.
+    ASSERT(index <= kMaxSixBitValue);
+    return ((hash >> 13) ^ (hash & 0x1fff)) | (index << 19) | (parenLocation << 25) |
+           (hasArrayOrBlockParamBit << 31);
 }
 
 }  // namespace sh
--- a/gfx/angle/checkout/src/compiler/translator/ImmutableString.h
+++ b/gfx/angle/checkout/src/compiler/translator/ImmutableString.h
@@ -123,17 +123,20 @@ class ImmutableString
                 hash = hash ^ (*data);
                 hash = hash * kFnvPrime;
                 ++data;
             }
             return hash;
         }
     };
 
-    uint32_t hash32() const;
+    // This hash encodes the opening parentheses location (if any), name length and whether the name
+    // contains { or [ characters in addition to a 19-bit hash. This way the hash is more useful for
+    // lookups. The string passed in should be at most 63 characters.
+    uint32_t mangledNameHash() const;
 
   private:
     const char *mData;
     size_t mLength;
 };
 
 }  // namespace sh
 
--- a/gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.h
+++ b/gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.h
@@ -42,17 +42,17 @@ class ImmutableStringBuilder
         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';
+            char digitChar = (digit < 10) ? (digit + '0') : (digit + ('a' - 10));
             mData[mPos++]  = digitChar;
             --index;
         }
         return;
     }
 
   private:
     inline static char *AllocateEmptyPoolCharArray(size_t strLength)
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/InitializeVariables.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-#include "compiler/translator/InitializeVariables.h"
-
-#include "angle_gl.h"
-#include "common/debug.h"
-#include "compiler/translator/FindMain.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/StaticType.h"
-#include "compiler/translator/SymbolTable.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
-    {
-        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());
-
-    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(TIntermSequence *mainBody,
-                    const InitVariableList &variables,
-                    TSymbolTable *symbolTable,
-                    int shaderVersion,
-                    const TExtensionBehavior &extensionBehavior,
-                    bool canUseLoopsToInitialize,
-                    bool highPrecisionSupported)
-{
-    for (const auto &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())
-        {
-            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
-        {
-            initializedSymbol = ReferenceGlobalVariable(tempVariableName, *symbolTable);
-        }
-        ASSERT(initializedSymbol != nullptr);
-
-        TIntermSequence *initCode = CreateInitCode(initializedSymbol, canUseLoopsToInitialize,
-                                                   highPrecisionSupported, 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);
-                    insertStatementsInParentBlock(
-                        TIntermSequence(), *CreateInitCode(symbol, mCanUseLoopsToInitialize,
-                                                           mHighPrecisionSupported, mSymbolTable));
-                }
-                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 anonymous
-
-TIntermSequence *CreateInitCode(const TIntermTyped *initializedSymbol,
-                                bool canUseLoopsToInitialize,
-                                bool highPrecisionSupported,
-                                TSymbolTable *symbolTable)
-{
-    TIntermSequence *initCode = new TIntermSequence();
-    AddZeroInitSequence(initializedSymbol, canUseLoopsToInitialize, highPrecisionSupported,
-                        initCode, symbolTable);
-    return initCode;
-}
-
-void InitializeUninitializedLocals(TIntermBlock *root,
-                                   int shaderVersion,
-                                   bool canUseLoopsToInitialize,
-                                   bool highPrecisionSupported,
-                                   TSymbolTable *symbolTable)
-{
-    InitializeLocalsTraverser traverser(shaderVersion, symbolTable, canUseLoopsToInitialize,
-                                        highPrecisionSupported);
-    root->traverse(&traverser);
-    traverser.updateTree();
-}
-
-void InitializeVariables(TIntermBlock *root,
-                         const InitVariableList &vars,
-                         TSymbolTable *symbolTable,
-                         int shaderVersion,
-                         const TExtensionBehavior &extensionBehavior,
-                         bool canUseLoopsToInitialize,
-                         bool highPrecisionSupported)
-{
-    TIntermBlock *body = FindMainBody(root);
-    InsertInitCode(body->getSequence(), vars, symbolTable, shaderVersion, extensionBehavior,
-                   canUseLoopsToInitialize, highPrecisionSupported);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/InitializeVariables.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-#ifndef COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_
-#define COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_
-
-#include <GLSLANG/ShaderLang.h>
-
-#include "compiler/translator/ExtensionBehavior.h"
-#include "compiler/translator/IntermNode.h"
-
-namespace sh
-{
-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.
-
-// Return 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.
-TIntermSequence *CreateInitCode(const TIntermTyped *initializedSymbol,
-                                bool canUseLoopsToInitialize,
-                                bool highPrecisionSupported,
-                                TSymbolTable *symbolTable);
-
-// Initialize all uninitialized local variables, so that undefined behavior is avoided.
-void InitializeUninitializedLocals(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.
-void InitializeVariables(TIntermBlock *root,
-                         const InitVariableList &vars,
-                         TSymbolTable *symbolTable,
-                         int shaderVersion,
-                         const TExtensionBehavior &extensionBehavior,
-                         bool canUseLoopsToInitialize,
-                         bool highPrecisionSupported);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_
--- a/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp
@@ -259,17 +259,17 @@ bool TIntermAggregate::replaceChildNode(
 
 bool TIntermBlock::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
 {
     return replaceChildNodeInternal(original, replacement);
 }
 
 bool TIntermFunctionPrototype::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
 {
-    return replaceChildNodeInternal(original, replacement);
+    return false;
 }
 
 bool TIntermDeclaration::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
 {
     return replaceChildNodeInternal(original, replacement);
 }
 
 bool TIntermAggregateBase::replaceChildNodeInternal(TIntermNode *original, TIntermNode *replacement)
@@ -684,22 +684,16 @@ void TIntermBlock::appendStatement(TInte
     // 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 TIntermFunctionPrototype::appendParameter(TIntermSymbol *parameter)
-{
-    ASSERT(parameter != nullptr);
-    mParameters.push_back(parameter);
-}
-
 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()));
@@ -796,30 +790,33 @@ TIntermAggregate *TIntermAggregate::shal
 }
 
 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), mAddIndexClamp(node.mAddIndexClamp)
 {
     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)
+    : 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)
 {
@@ -1042,24 +1039,25 @@ void TIntermUnary::promote()
             mType.setQualifier(resultQualifier);
             break;
     }
 }
 
 TIntermSwizzle::TIntermSwizzle(TIntermTyped *operand, const TVector<int> &swizzleOffsets)
     : TIntermExpression(TType(EbtFloat, EbpUndefined)),
       mOperand(operand),
-      mSwizzleOffsets(swizzleOffsets)
+      mSwizzleOffsets(swizzleOffsets),
+      mHasFoldedDuplicateOffsets(false)
 {
     ASSERT(mSwizzleOffsets.size() <= 4);
     promote();
 }
 
-TIntermUnary::TIntermUnary(TOperator op, TIntermTyped *operand)
-    : TIntermOperator(op), mOperand(operand), mUseEmulatedFunction(false)
+TIntermUnary::TIntermUnary(TOperator op, TIntermTyped *operand, const TFunction *function)
+    : TIntermOperator(op), mOperand(operand), mUseEmulatedFunction(false), mFunction(function)
 {
     promote();
 }
 
 TIntermBinary::TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right)
     : TIntermOperator(op), mLeft(left), mRight(right), mAddIndexClamp(false)
 {
     promote();
@@ -1168,28 +1166,37 @@ void TIntermSwizzle::promote()
 
     auto numFields = mSwizzleOffsets.size();
     setType(TType(mOperand->getBasicType(), mOperand->getPrecision(), resultQualifier,
                   static_cast<unsigned char>(numFields)));
 }
 
 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)
@@ -1473,16 +1480,34 @@ const TConstantUnion *TIntermConstantUni
     {
         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)
--- a/gfx/angle/checkout/src/compiler/translator/IntermNode.h
+++ b/gfx/angle/checkout/src/compiler/translator/IntermNode.h
@@ -426,23 +426,25 @@ class TIntermSwizzle : public TIntermExp
     bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
 
     bool hasSideEffects() const override { return mOperand->hasSideEffects(); }
 
     TIntermTyped *getOperand() { return mOperand; }
     void writeOffsetsAsXYZW(TInfoSinkBase *out) const;
 
     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();
 
     TIntermSwizzle(const TIntermSwizzle &node);  // Note: not deleted, just private!
 };
 
 //
@@ -498,39 +500,43 @@ class TIntermBinary : public TIntermOper
 };
 
 //
 // Nodes for unary math operators.
 //
 class TIntermUnary : public TIntermOperator
 {
   public:
-    TIntermUnary(TOperator op, TIntermTyped *operand);
+    TIntermUnary(TOperator op, TIntermTyped *operand, const TFunction *function);
 
     TIntermTyped *deepCopy() const override { return new TIntermUnary(*this); }
 
     void traverse(TIntermTraverser *it) override;
     TIntermUnary *getAsUnaryNode() override { return this; }
     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();
 
     TIntermUnary(const TIntermUnary &node);  // note: not deleted, just private!
 };
 
 typedef TVector<TIntermNode *> TIntermSequence;
 typedef TVector<int> TQualifierList;
@@ -655,17 +661,17 @@ class TIntermBlock : public TIntermNode,
     const TIntermSequence *getSequence() const override { return &mStatements; }
 
   protected:
     TIntermSequence mStatements;
 };
 
 // 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 TIntermAggregateBase
+class TIntermFunctionPrototype : public TIntermTyped
 {
   public:
     TIntermFunctionPrototype(const TFunction *function);
     ~TIntermFunctionPrototype() {}
 
     TIntermFunctionPrototype *getAsFunctionPrototypeNode() override { return this; }
     void traverse(TIntermTraverser *it) override;
     bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
@@ -678,27 +684,19 @@ class TIntermFunctionPrototype : public 
         return nullptr;
     }
     bool hasSideEffects() const override
     {
         UNREACHABLE();
         return true;
     }
 
-    // Only intended for initially building the declaration.
-    void appendParameter(TIntermSymbol *parameter);
-
-    TIntermSequence *getSequence() override { return &mParameters; }
-    const TIntermSequence *getSequence() const override { return &mParameters; }
-
     const TFunction *getFunction() const { return mFunction; }
 
   protected:
-    TIntermSequence mParameters;
-
     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:
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/IntermNodePatternMatcher.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-//
-// Copyright (c) 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/IntermNodePatternMatcher.h"
-
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/SymbolTable.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::IsDynamicIndexingOfVectorOrMatrix(TIntermBinary *node)
-{
-    return node->getOp() == EOpIndexIndirect && !node->getLeft()->isArray() &&
-           node->getLeft()->getBasicType() != EbtStruct;
-}
-
-bool IntermNodePatternMatcher::matchInternal(TIntermBinary *node, TIntermNode *parentNode)
-{
-    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)
-{
-    if ((mMask & kArrayLengthMethod) != 0)
-    {
-        if (node->getOp() == EOpArrayLength)
-        {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool IntermNodePatternMatcher::match(TIntermBinary *node, TIntermNode *parentNode)
-{
-    // 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)
-{
-    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)
-{
-    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()) && !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)
-{
-    if ((mMask & kUnfoldedShortCircuitExpression) != 0)
-    {
-        return true;
-    }
-    return false;
-}
-
-bool IntermNodePatternMatcher::match(TIntermDeclaration *node)
-{
-    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
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/IntermNodePatternMatcher.h
+++ /dev/null
@@ -1,79 +0,0 @@
-//
-// Copyright (c) 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_INTERMNODEPATTERNMATCHER_H_
-#define COMPILER_TRANSLATOR_INTERMNODEPATTERNMATCHER_H_
-
-namespace sh
-{
-
-class TIntermAggregate;
-class TIntermBinary;
-class TIntermDeclaration;
-class TIntermNode;
-class TIntermTernary;
-class TIntermUnary;
-
-class IntermNodePatternMatcher
-{
-  public:
-    static bool IsDynamicIndexingOfVectorOrMatrix(TIntermBinary *node);
-
-    enum PatternType
-    {
-        // Matches expressions that are unfolded to if statements by UnfoldShortCircuitToIf
-        kUnfoldedShortCircuitExpression = 0x0001,
-
-        // Matches expressions that return arrays with the exception of simple statements where a
-        // constructor or function call result is assigned.
-        kExpressionReturningArray = 0x0001 << 1,
-
-        // Matches dynamic indexing of vectors or matrices in l-values.
-        kDynamicIndexingOfVectorOrMatrixInLValue = 0x0001 << 2,
-
-        // Matches declarations with more than one declared variables.
-        kMultiDeclaration = 0x0001 << 3,
-
-        // Matches declarations of arrays.
-        kArrayDeclaration = 0x0001 << 4,
-
-        // Matches declarations of structs where the struct type does not have a name.
-        kNamelessStructDeclaration = 0x0001 << 5,
-
-        // Matches array length() method.
-        kArrayLengthMethod = 0x0001 << 6,
-
-        // Matches a vector or matrix constructor whose arguments are scalarized by the
-        // SH_SCALARIZE_VEC_OR_MAT_CONSTRUCTOR_ARGUMENTS workaround.
-        kScalarizedVecOrMatConstructor = 0x0001 << 7
-    };
-    IntermNodePatternMatcher(const unsigned int mask);
-
-    bool match(TIntermUnary *node);
-
-    bool match(TIntermBinary *node, TIntermNode *parentNode);
-
-    // Use this version for checking binary node matches in case you're using flag
-    // kDynamicIndexingOfVectorOrMatrixInLValue.
-    bool match(TIntermBinary *node, TIntermNode *parentNode, bool isLValueRequiredHere);
-
-    bool match(TIntermAggregate *node, TIntermNode *parentNode);
-    bool match(TIntermTernary *node);
-    bool match(TIntermDeclaration *node);
-
-  private:
-    const unsigned int mMask;
-
-    bool matchInternal(TIntermBinary *node, TIntermNode *parentNode);
-};
-
-}  // namespace sh
-
-#endif
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/IntermNode_util.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-//
-// Copyright (c) 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/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 typecheck.
-                    // 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;
-    }
-
-    if (type.getBasicType() == EbtVoid)
-    {
-        // Void array. This happens only on error condition, similarly to the case above. We don't
-        // have a constructor operator for void, so this needs special handling. We'll end up with a
-        // value without the array type, but that should not be a problem.
-        while (constType.isArray())
-        {
-            constType.toArrayElementType();
-        }
-        return CreateZeroNode(constType);
-    }
-
-    TIntermSequence *arguments = new TIntermSequence();
-
-    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 *CreateIndexNode(int index)
-{
-    TConstantUnion *u = new TConstantUnion[1];
-    u[0].setIConst(index);
-
-    TType type(EbtInt, EbpUndefined, EvqConst, 1);
-    TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
-    return node;
-}
-
-TIntermConstantUnion *CreateBoolNode(bool value)
-{
-    TConstantUnion *u = new TConstantUnion[1];
-    u[0].setBConst(value);
-
-    TType type(EbtBool, EbpUndefined, EvqConst, 1);
-    TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
-    return node;
-}
-
-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, ImmutableString(""), 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;
-}
-
-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 TVariable *var = reinterpret_cast<const TVariable *>(symbolTable.findGlobal(name));
-    ASSERT(var);
-    return new TIntermSymbol(var);
-}
-
-TIntermSymbol *ReferenceBuiltInVariable(const ImmutableString &name,
-                                        const TSymbolTable &symbolTable,
-                                        int shaderVersion)
-{
-    const TVariable *var =
-        reinterpret_cast<const TVariable *>(symbolTable.findBuiltIn(name, shaderVersion, true));
-    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 (op != EOpCallBuiltInFunction && arguments->size() == 1)
-    {
-        return new TIntermUnary(op, arguments->at(0)->getAsTyped());
-    }
-    return TIntermAggregate::CreateBuiltInFunctionCall(*fn, arguments);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/IntermNode_util.h
+++ /dev/null
@@ -1,67 +0,0 @@
-//
-// Copyright (c) 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"
-
-namespace sh
-{
-
-class TSymbolTable;
-class TVariable;
-
-TIntermFunctionPrototype *CreateInternalFunctionPrototypeNode(const TFunction &func);
-TIntermFunctionDefinition *CreateInternalFunctionDefinitionNode(const TFunction &func,
-                                                                TIntermBlock *functionBody);
-
-TIntermTyped *CreateZeroNode(const TType &type);
-TIntermConstantUnion *CreateIndexNode(int index);
-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);
-
-// 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 access desktop GLSL built-ins that are hidden from the parser.
-TIntermSymbol *ReferenceBuiltInVariable(const ImmutableString &name,
-                                        const TSymbolTable &symbolTable,
-                                        int shaderVersion);
-
-TIntermTyped *CreateBuiltInFunctionCallNode(const char *name,
-                                            TIntermSequence *arguments,
-                                            const TSymbolTable &symbolTable,
-                                            int shaderVersion);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_INTERMNODEUTIL_H_
\ No newline at end of file
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/IntermTraverse.cpp
+++ /dev/null
@@ -1,851 +0,0 @@
-//
-// Copyright (c) 2002-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/IntermTraverse.h"
-
-#include "compiler/translator/InfoSink.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/SymbolTable.h"
-
-namespace sh
-{
-
-void TIntermSymbol::traverse(TIntermTraverser *it)
-{
-    it->traverseSymbol(this);
-}
-
-void TIntermRaw::traverse(TIntermTraverser *it)
-{
-    it->traverseRaw(this);
-}
-
-void TIntermConstantUnion::traverse(TIntermTraverser *it)
-{
-    it->traverseConstantUnion(this);
-}
-
-void TIntermSwizzle::traverse(TIntermTraverser *it)
-{
-    it->traverseSwizzle(this);
-}
-
-void TIntermBinary::traverse(TIntermTraverser *it)
-{
-    it->traverseBinary(this);
-}
-
-void TIntermUnary::traverse(TIntermTraverser *it)
-{
-    it->traverseUnary(this);
-}
-
-void TIntermTernary::traverse(TIntermTraverser *it)
-{
-    it->traverseTernary(this);
-}
-
-void TIntermIfElse::traverse(TIntermTraverser *it)
-{
-    it->traverseIfElse(this);
-}
-
-void TIntermSwitch::traverse(TIntermTraverser *it)
-{
-    it->traverseSwitch(this);
-}
-
-void TIntermCase::traverse(TIntermTraverser *it)
-{
-    it->traverseCase(this);
-}
-
-void TIntermFunctionDefinition::traverse(TIntermTraverser *it)
-{
-    it->traverseFunctionDefinition(this);
-}
-
-void TIntermBlock::traverse(TIntermTraverser *it)
-{
-    it->traverseBlock(this);
-}
-
-void TIntermInvariantDeclaration::traverse(TIntermTraverser *it)
-{
-    it->traverseInvariantDeclaration(this);
-}
-
-void TIntermDeclaration::traverse(TIntermTraverser *it)
-{
-    it->traverseDeclaration(this);
-}
-
-void TIntermFunctionPrototype::traverse(TIntermTraverser *it)
-{
-    it->traverseFunctionPrototype(this);
-}
-
-void TIntermAggregate::traverse(TIntermTraverser *it)
-{
-    it->traverseAggregate(this);
-}
-
-void TIntermLoop::traverse(TIntermTraverser *it)
-{
-    it->traverseLoop(this);
-}
-
-void TIntermBranch::traverse(TIntermTraverser *it)
-{
-    it->traverseBranch(this);
-}
-
-TIntermTraverser::TIntermTraverser(bool preVisit,
-                                   bool inVisit,
-                                   bool postVisit,
-                                   TSymbolTable *symbolTable)
-    : preVisit(preVisit),
-      inVisit(inVisit),
-      postVisit(postVisit),
-      mDepth(-1),
-      mMaxDepth(0),
-      mInGlobalScope(true),
-      mSymbolTable(symbolTable)
-{
-}
-
-TIntermTraverser::~TIntermTraverser()
-{
-}
-
-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 TLValueTrackingTraverser::setInFunctionCallOutParameter(bool inOutParameter)
-{
-    mInFunctionCallOutParameter = inOutParameter;
-}
-
-bool TLValueTrackingTraverser::isInFunctionCallOutParameter() const
-{
-    return mInFunctionCallOutParameter;
-}
-
-//
-// Traverse the intermediate representation tree, and
-// call a node type specific function for each node.
-// Done recursively through the member function Traverse().
-// Node types can be skipped if their function to call is 0,
-// but their subtree will still be traversed.
-// Nodes with children can have their whole subtree skipped
-// if preVisit is turned on and the type specific function
-// returns false.
-//
-
-//
-// Traversal functions for terminals are straighforward....
-//
-void TIntermTraverser::traverseSymbol(TIntermSymbol *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-    visitSymbol(node);
-}
-
-void TIntermTraverser::traverseConstantUnion(TIntermConstantUnion *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-    visitConstantUnion(node);
-}
-
-void TIntermTraverser::traverseSwizzle(TIntermSwizzle *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-
-    bool visit = true;
-
-    if (preVisit)
-        visit = visitSwizzle(PreVisit, node);
-
-    if (visit)
-    {
-        node->getOperand()->traverse(this);
-    }
-
-    if (visit && postVisit)
-        visitSwizzle(PostVisit, node);
-}
-
-//
-// Traverse a binary node.
-//
-void TIntermTraverser::traverseBinary(TIntermBinary *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-
-    bool visit = true;
-
-    //
-    // visit the node before children if pre-visiting.
-    //
-    if (preVisit)
-        visit = visitBinary(PreVisit, node);
-
-    //
-    // Visit the children, in the right order.
-    //
-    if (visit)
-    {
-        if (node->getLeft())
-            node->getLeft()->traverse(this);
-
-        if (inVisit)
-            visit = visitBinary(InVisit, node);
-
-        if (visit && node->getRight())
-            node->getRight()->traverse(this);
-    }
-
-    //
-    // Visit the node after the children, if requested and the traversal
-    // hasn't been cancelled yet.
-    //
-    if (visit && postVisit)
-        visitBinary(PostVisit, node);
-}
-
-void TLValueTrackingTraverser::traverseBinary(TIntermBinary *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-
-    bool visit = true;
-
-    //
-    // visit the node before children if pre-visiting.
-    //
-    if (preVisit)
-        visit = visitBinary(PreVisit, node);
-
-    //
-    // Visit the children, in the right order.
-    //
-    if (visit)
-    {
-        // Some binary operations like indexing can be inside an expression which must be an
-        // l-value.
-        bool parentOperatorRequiresLValue     = operatorRequiresLValue();
-        bool parentInFunctionCallOutParameter = isInFunctionCallOutParameter();
-        if (node->isAssignment())
-        {
-            ASSERT(!isLValueRequiredHere());
-            setOperatorRequiresLValue(true);
-        }
-
-        if (node->getLeft())
-            node->getLeft()->traverse(this);
-
-        if (inVisit)
-            visit = visitBinary(InVisit, node);
-
-        if (node->isAssignment())
-            setOperatorRequiresLValue(false);
-
-        // 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);
-        }
-
-        if (visit && node->getRight())
-            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 (visit && postVisit)
-        visitBinary(PostVisit, node);
-}
-
-//
-// Traverse a unary node.  Same comments in binary node apply here.
-//
-void TIntermTraverser::traverseUnary(TIntermUnary *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-
-    bool visit = true;
-
-    if (preVisit)
-        visit = visitUnary(PreVisit, node);
-
-    if (visit)
-    {
-        node->getOperand()->traverse(this);
-    }
-
-    if (visit && postVisit)
-        visitUnary(PostVisit, node);
-}
-
-void TLValueTrackingTraverser::traverseUnary(TIntermUnary *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-
-    bool visit = true;
-
-    if (preVisit)
-        visit = visitUnary(PreVisit, node);
-
-    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 (visit && postVisit)
-        visitUnary(PostVisit, node);
-}
-
-// Traverse a function definition node.
-void TIntermTraverser::traverseFunctionDefinition(TIntermFunctionDefinition *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-
-    bool visit = true;
-
-    if (preVisit)
-        visit = visitFunctionDefinition(PreVisit, node);
-
-    if (visit)
-    {
-        mInGlobalScope = false;
-
-        node->getFunctionPrototype()->traverse(this);
-        if (inVisit)
-            visit = visitFunctionDefinition(InVisit, node);
-        node->getBody()->traverse(this);
-
-        mInGlobalScope = true;
-    }
-
-    if (visit && postVisit)
-        visitFunctionDefinition(PostVisit, node);
-}
-
-// Traverse a block node.
-void TIntermTraverser::traverseBlock(TIntermBlock *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-    pushParentBlock(node);
-
-    bool visit = true;
-
-    TIntermSequence *sequence = node->getSequence();
-
-    if (preVisit)
-        visit = visitBlock(PreVisit, node);
-
-    if (visit)
-    {
-        for (auto *child : *sequence)
-        {
-            child->traverse(this);
-            if (visit && inVisit)
-            {
-                if (child != sequence->back())
-                    visit = visitBlock(InVisit, node);
-            }
-
-            incrementParentBlockPos();
-        }
-    }
-
-    if (visit && postVisit)
-        visitBlock(PostVisit, node);
-
-    popParentBlock();
-}
-
-void TIntermTraverser::traverseInvariantDeclaration(TIntermInvariantDeclaration *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-
-    bool visit = true;
-
-    if (preVisit)
-    {
-        visit = visitInvariantDeclaration(PreVisit, node);
-    }
-
-    if (visit)
-    {
-        node->getSymbol()->traverse(this);
-        if (postVisit)
-        {
-            visitInvariantDeclaration(PostVisit, node);
-        }
-    }
-}
-
-// Traverse a declaration node.
-void TIntermTraverser::traverseDeclaration(TIntermDeclaration *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-
-    bool visit = true;
-
-    TIntermSequence *sequence = node->getSequence();
-
-    if (preVisit)
-        visit = visitDeclaration(PreVisit, node);
-
-    if (visit)
-    {
-        for (auto *child : *sequence)
-        {
-            child->traverse(this);
-            if (visit && inVisit)
-            {
-                if (child != sequence->back())
-                    visit = visitDeclaration(InVisit, node);
-            }
-        }
-    }
-
-    if (visit && postVisit)
-        visitDeclaration(PostVisit, node);
-}
-
-void TIntermTraverser::traverseFunctionPrototype(TIntermFunctionPrototype *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-
-    bool visit = true;
-
-    TIntermSequence *sequence = node->getSequence();
-
-    if (preVisit)
-        visit = visitFunctionPrototype(PreVisit, node);
-
-    if (visit)
-    {
-        for (auto *child : *sequence)
-        {
-            child->traverse(this);
-            if (visit && inVisit)
-            {
-                if (child != sequence->back())
-                    visit = visitFunctionPrototype(InVisit, node);
-            }
-        }
-    }
-
-    if (visit && postVisit)
-        visitFunctionPrototype(PostVisit, node);
-}
-
-// Traverse an aggregate node.  Same comments in binary node apply here.
-void TIntermTraverser::traverseAggregate(TIntermAggregate *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-
-    bool visit = true;
-
-    TIntermSequence *sequence = node->getSequence();
-
-    if (preVisit)
-        visit = visitAggregate(PreVisit, node);
-
-    if (visit)
-    {
-        for (auto *child : *sequence)
-        {
-            child->traverse(this);
-            if (visit && inVisit)
-            {
-                if (child != sequence->back())
-                    visit = visitAggregate(InVisit, node);
-            }
-        }
-    }
-
-    if (visit && postVisit)
-        visitAggregate(PostVisit, 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;
-}
-
-void TIntermTraverser::updateTree()
-{
-    // Sort the insertions so that insertion position is decreasing. This way multiple insertions to
-    // the same parent node are handled correctly.
-    std::sort(mInsertions.begin(), mInsertions.end(), CompareInsertion);
-    for (size_t ii = 0; ii < mInsertions.size(); ++ii)
-    {
-        // We can't know here what the intended ordering of two insertions to the same position is,
-        // so it is not supported.
-        ASSERT(ii == 0 || mInsertions[ii].position != mInsertions[ii - 1].position ||
-               mInsertions[ii].parent != mInsertions[ii - 1].parent);
-        const NodeInsertMultipleEntry &insertion = mInsertions[ii];
-        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);
-
-        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();
-}
-
-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));
-}
-
-TLValueTrackingTraverser::TLValueTrackingTraverser(bool preVisit,
-                                                   bool inVisit,
-                                                   bool postVisit,
-                                                   TSymbolTable *symbolTable)
-    : TIntermTraverser(preVisit, inVisit, postVisit, symbolTable),
-      mOperatorRequiresLValue(false),
-      mInFunctionCallOutParameter(false)
-{
-    ASSERT(symbolTable);
-}
-
-void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-
-    bool visit = true;
-
-    TIntermSequence *sequence = node->getSequence();
-
-    if (preVisit)
-        visit = visitAggregate(PreVisit, node);
-
-    if (visit)
-    {
-        size_t paramIndex = 0u;
-        for (auto *child : *sequence)
-        {
-            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).type->getQualifier();
-                setInFunctionCallOutParameter(qualifier == EvqOut || qualifier == EvqInOut);
-                ++paramIndex;
-            }
-            else
-            {
-                ASSERT(node->isConstructor());
-            }
-
-            child->traverse(this);
-            if (visit && inVisit)
-            {
-                if (child != sequence->back())
-                    visit = visitAggregate(InVisit, node);
-            }
-        }
-        setInFunctionCallOutParameter(false);
-    }
-
-    if (visit && postVisit)
-        visitAggregate(PostVisit, node);
-}
-
-//
-// Traverse a ternary node.  Same comments in binary node apply here.
-//
-void TIntermTraverser::traverseTernary(TIntermTernary *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-
-    bool visit = true;
-
-    if (preVisit)
-        visit = visitTernary(PreVisit, node);
-
-    if (visit)
-    {
-        node->getCondition()->traverse(this);
-        if (node->getTrueExpression())
-            node->getTrueExpression()->traverse(this);
-        if (node->getFalseExpression())
-            node->getFalseExpression()->traverse(this);
-    }
-
-    if (visit && postVisit)
-        visitTernary(PostVisit, node);
-}
-
-// Traverse an if-else node.  Same comments in binary node apply here.
-void TIntermTraverser::traverseIfElse(TIntermIfElse *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-
-    bool visit = true;
-
-    if (preVisit)
-        visit = visitIfElse(PreVisit, node);
-
-    if (visit)
-    {
-        node->getCondition()->traverse(this);
-        if (node->getTrueBlock())
-            node->getTrueBlock()->traverse(this);
-        if (node->getFalseBlock())
-            node->getFalseBlock()->traverse(this);
-    }
-
-    if (visit && postVisit)
-        visitIfElse(PostVisit, node);
-}
-
-//
-// Traverse a switch node.  Same comments in binary node apply here.
-//
-void TIntermTraverser::traverseSwitch(TIntermSwitch *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-
-    bool visit = true;
-
-    if (preVisit)
-        visit = visitSwitch(PreVisit, node);
-
-    if (visit)
-    {
-        node->getInit()->traverse(this);
-        if (inVisit)
-            visit = visitSwitch(InVisit, node);
-        if (visit && node->getStatementList())
-            node->getStatementList()->traverse(this);
-    }
-
-    if (visit && postVisit)
-        visitSwitch(PostVisit, node);
-}
-
-//
-// Traverse a case node.  Same comments in binary node apply here.
-//
-void TIntermTraverser::traverseCase(TIntermCase *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-
-    bool visit = true;
-
-    if (preVisit)
-        visit = visitCase(PreVisit, node);
-
-    if (visit && node->getCondition())
-    {
-        node->getCondition()->traverse(this);
-    }
-
-    if (visit && postVisit)
-        visitCase(PostVisit, node);
-}
-
-//
-// Traverse a loop node.  Same comments in binary node apply here.
-//
-void TIntermTraverser::traverseLoop(TIntermLoop *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-
-    bool visit = true;
-
-    if (preVisit)
-        visit = visitLoop(PreVisit, node);
-
-    if (visit)
-    {
-        if (node->getInit())
-            node->getInit()->traverse(this);
-
-        if (node->getCondition())
-            node->getCondition()->traverse(this);
-
-        if (node->getBody())
-            node->getBody()->traverse(this);
-
-        if (node->getExpression())
-            node->getExpression()->traverse(this);
-    }
-
-    if (visit && postVisit)
-        visitLoop(PostVisit, node);
-}
-
-//
-// Traverse a branch node.  Same comments in binary node apply here.
-//
-void TIntermTraverser::traverseBranch(TIntermBranch *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-
-    bool visit = true;
-
-    if (preVisit)
-        visit = visitBranch(PreVisit, node);
-
-    if (visit && node->getExpression())
-    {
-        node->getExpression()->traverse(this);
-    }
-
-    if (visit && postVisit)
-        visitBranch(PostVisit, node);
-}
-
-void TIntermTraverser::traverseRaw(TIntermRaw *node)
-{
-    ScopedNodeInTraversalPath addToPath(this, node);
-    visitRaw(node);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/IntermTraverse.h
+++ /dev/null
@@ -1,320 +0,0 @@
-//
-// Copyright (c) 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_INTERMTRAVERSE_H_
-#define COMPILER_TRANSLATOR_INTERMTRAVERSE_H_
-
-#include "compiler/translator/IntermNode.h"
-
-namespace sh
-{
-
-class TSymbolTable;
-class TSymbolUniqueId;
-
-enum Visit
-{
-    PreVisit,
-    InVisit,
-    PostVisit
-};
-
-// 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.
-class TIntermTraverser : angle::NonCopyable
-{
-  public:
-    POOL_ALLOCATOR_NEW_DELETE();
-    TIntermTraverser(bool preVisit,
-                     bool inVisit,
-                     bool postVisit,
-                     TSymbolTable *symbolTable = nullptr);
-    virtual ~TIntermTraverser();
-
-    virtual void visitSymbol(TIntermSymbol *node) {}
-    virtual void visitRaw(TIntermRaw *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 bool visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node)
-    {
-        return true;
-    }
-    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 visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *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; }
-
-    // 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.
-    virtual void traverseSymbol(TIntermSymbol *node);
-    virtual void traverseRaw(TIntermRaw *node);
-    virtual void traverseConstantUnion(TIntermConstantUnion *node);
-    virtual void traverseSwizzle(TIntermSwizzle *node);
-    virtual void traverseBinary(TIntermBinary *node);
-    virtual void traverseUnary(TIntermUnary *node);
-    virtual void traverseTernary(TIntermTernary *node);
-    virtual void traverseIfElse(TIntermIfElse *node);
-    virtual void traverseSwitch(TIntermSwitch *node);
-    virtual void traverseCase(TIntermCase *node);
-    virtual void traverseFunctionPrototype(TIntermFunctionPrototype *node);
-    virtual void traverseFunctionDefinition(TIntermFunctionDefinition *node);
-    virtual void traverseAggregate(TIntermAggregate *node);
-    virtual void traverseBlock(TIntermBlock *node);
-    virtual void traverseInvariantDeclaration(TIntermInvariantDeclaration *node);
-    virtual void traverseDeclaration(TIntermDeclaration *node);
-    virtual void traverseLoop(TIntermLoop *node);
-    virtual void traverseBranch(TIntermBranch *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.
-    void updateTree();
-
-  protected:
-    // Should only be called from traverse*() functions
-    void incrementDepth(TIntermNode *current)
-    {
-        mDepth++;
-        mMaxDepth = std::max(mMaxDepth, mDepth);
-        mPath.push_back(current);
-    }
-
-    // Should only be called from traverse*() functions
-    void decrementDepth()
-    {
-        mDepth--;
-        mPath.pop_back();
-    }
-
-    // RAII helper for incrementDepth/decrementDepth
-    class ScopedNodeInTraversalPath
-    {
-      public:
-        ScopedNodeInTraversalPath(TIntermTraverser *traverser, TIntermNode *current)
-            : mTraverser(traverser)
-        {
-            mTraverser->incrementDepth(current);
-        }
-        ~ScopedNodeInTraversalPath() { mTraverser->decrementDepth(); }
-
-      private:
-        TIntermTraverser *mTraverser;
-    };
-
-    TIntermNode *getParentNode() { 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)
-    {
-        if (mPath.size() > n + 1u)
-        {
-            return mPath[mPath.size() - n - 2u];
-        }
-        return nullptr;
-    }
-
-    const TIntermBlock *getParentBlock() const;
-
-    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 *_parent,
-                                     TIntermNode *_original,
-                                     TIntermSequence _replacements)
-            : parent(_parent), original(_original), replacements(_replacements)
-        {
-        }
-
-        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);
-
-    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);
-
-    const bool preVisit;
-    const bool inVisit;
-    const bool postVisit;
-
-    int mDepth;
-    int mMaxDepth;
-
-    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;
-
-    // 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);
-    virtual ~TLValueTrackingTraverser() {}
-
-    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_INTERMTRAVERSE_H_
--- a/gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.cpp
@@ -1,46 +1,32 @@
 //
 // Copyright (c) 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/IntermTraverse.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, true, false), mDepthLimit(depthLimit)
+    MaxDepthTraverser(int depthLimit) : TIntermTraverser(true, false, false, nullptr)
     {
+        setMaxAllowedDepth(depthLimit);
     }
-
-    bool visitBinary(Visit, TIntermBinary *) override { return depthCheck(); }
-    bool visitUnary(Visit, TIntermUnary *) override { return depthCheck(); }
-    bool visitTernary(Visit, TIntermTernary *) override { return depthCheck(); }
-    bool visitSwizzle(Visit, TIntermSwizzle *) override { return depthCheck(); }
-    bool visitIfElse(Visit, TIntermIfElse *) override { return depthCheck(); }
-    bool visitAggregate(Visit, TIntermAggregate *) override { return depthCheck(); }
-    bool visitBlock(Visit, TIntermBlock *) override { return depthCheck(); }
-    bool visitLoop(Visit, TIntermLoop *) override { return depthCheck(); }
-    bool visitBranch(Visit, TIntermBranch *) override { return depthCheck(); }
-
-  protected:
-    bool depthCheck() const { return mMaxDepth < mDepthLimit; }
-
-    int mDepthLimit;
 };
 
 }  // anonymous namespace
 
 bool IsASTDepthBelowLimit(TIntermNode *root, int maxDepth)
 {
     MaxDepthTraverser traverser(maxDepth + 1);
     root->traverse(&traverser);
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/NodeSearch.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// NodeSearch.h: Utilities for searching translator node graphs
-//
-
-#ifndef COMPILER_TRANSLATOR_NODESEARCH_H_
-#define COMPILER_TRANSLATOR_NODESEARCH_H_
-
-#include "compiler/translator/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:
-    virtual bool visitBranch(Visit visit, TIntermBranch *node)
-    {
-        switch (node->getFlowOp())
-        {
-            case EOpKill:
-                mFound = true;
-                break;
-
-            default:
-                break;
-        }
-
-        return !mFound;
-    }
-};
-}
-
-#endif  // COMPILER_TRANSLATOR_NODESEARCH_H_
--- a/gfx/angle/checkout/src/compiler/translator/OutputGLSL.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/OutputGLSL.cpp
@@ -89,18 +89,18 @@ ImmutableString TOutputGLSL::translateTe
                                          "texture2DProjGradEXT",
                                          "texture2DProjGradARB",
                                          "textureCubeGradEXT",
                                          "textureCubeGradARB",
                                          nullptr,
                                          nullptr};
     static const char *legacyToCoreRename[] = {
         "texture2D", "texture", "texture2DProj", "textureProj", "texture2DLod", "textureLod",
-        "texture2DProjLod", "textureProjLod", "texture2DRect", "texture", "textureCube", "texture",
-        "textureCubeLod", "textureLod",
+        "texture2DProjLod", "textureProjLod", "texture2DRect", "texture", "texture2DRectProj",
+        "textureProj", "textureCube", "texture", "textureCubeLod", "textureLod",
         // Extensions
         "texture2DLodEXT", "textureLod", "texture2DProjLodEXT", "textureProjLod",
         "textureCubeLodEXT", "textureLod", "texture2DGradEXT", "textureGrad",
         "texture2DProjGradEXT", "textureProjGrad", "textureCubeGradEXT", "textureGrad", nullptr,
         nullptr};
     const char **mapping =
         (sh::IsGLSL130OrNewer(getShaderOutput())) ? legacyToCoreRename : simpleRename;
 
--- a/gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.cpp
@@ -323,34 +323,33 @@ void TOutputGLSLBase::writeVariableType(
     else
     {
         if (writeVariablePrecision(type.getPrecision()))
             out << " ";
         out << getTypeName(type);
     }
 }
 
-void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence &args)
+void TOutputGLSLBase::writeFunctionParameters(const TFunction *func)
 {
     TInfoSinkBase &out = objSink();
-    for (TIntermSequence::const_iterator iter = args.begin(); iter != args.end(); ++iter)
+    size_t paramCount  = func->getParamCount();
+    for (size_t i = 0; i < paramCount; ++i)
     {
-        const TIntermSymbol *arg = (*iter)->getAsSymbolNode();
-        ASSERT(arg != nullptr);
-
-        const TType &type = arg->getType();
+        const TVariable *param = func->getParam(i);
+        const TType &type      = param->getType();
         writeVariableType(type);
 
-        if (arg->variable().symbolType() != SymbolType::Empty)
-            out << " " << hashName(&arg->variable());
+        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 (iter != args.end() - 1)
+        if (i != paramCount - 1)
             out << ", ";
     }
 }
 
 const TConstantUnion *TOutputGLSLBase::writeConstantUnion(const TType &type,
                                                           const TConstantUnion *pConstUnion)
 {
     TInfoSinkBase &out = objSink();
@@ -842,34 +841,34 @@ bool TOutputGLSLBase::visitCase(Visit vi
         return false;
     }
 }
 
 bool TOutputGLSLBase::visitBlock(Visit visit, TIntermBlock *node)
 {
     TInfoSinkBase &out = objSink();
     // Scope the blocks except when at the global scope.
-    if (mDepth > 0)
+    if (getCurrentTraversalDepth() > 0)
     {
         out << "{\n";
     }
 
     for (TIntermSequence::const_iterator iter = node->getSequence()->begin();
          iter != node->getSequence()->end(); ++iter)
     {
         TIntermNode *curNode = *iter;
         ASSERT(curNode != nullptr);
         curNode->traverse(this);
 
         if (isSingleStatement(curNode))
             out << ";\n";
     }
 
     // Scope the blocks except when at the global scope.
-    if (mDepth > 0)
+    if (getCurrentTraversalDepth() > 0)
     {
         out << "}\n";
     }
     return false;
 }
 
 bool TOutputGLSLBase::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
 {
@@ -885,33 +884,30 @@ bool TOutputGLSLBase::visitInvariantDecl
 {
     TInfoSinkBase &out = objSink();
     ASSERT(visit == PreVisit);
     const TIntermSymbol *symbol = node->getSymbol();
     out << "invariant " << hashName(&symbol->variable());
     return false;
 }
 
-bool TOutputGLSLBase::visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node)
+void TOutputGLSLBase::visitFunctionPrototype(TIntermFunctionPrototype *node)
 {
     TInfoSinkBase &out = objSink();
-    ASSERT(visit == PreVisit);
 
     const TType &type = node->getType();
     writeVariableType(type);
     if (type.isArray())
         out << ArrayString(type);
 
     out << " " << hashFunctionNameIfNeeded(node->getFunction());
 
     out << "(";
-    writeFunctionParameters(*(node->getSequence()));
+    writeFunctionParameters(node->getFunction());
     out << ")";
-
-    return false;
 }
 
 bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
 {
     bool visitChildren       = true;
     TInfoSinkBase &out       = objSink();
     switch (node->getOp())
     {
--- a/gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.h
+++ b/gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.h
@@ -6,17 +6,17 @@
 
 #ifndef COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_
 #define COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_
 
 #include <set>
 
 #include "compiler/translator/HashNames.h"
 #include "compiler/translator/InfoSink.h"
-#include "compiler/translator/IntermTraverse.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
 
 namespace sh
 {
 
 class TOutputGLSLBase : public TIntermTraverser
 {
   public:
     TOutputGLSLBase(TInfoSinkBase &objSink,
@@ -39,31 +39,31 @@ class TOutputGLSLBase : public TIntermTr
   protected:
     TInfoSinkBase &objSink() { return mObjSink; }
     void writeFloat(TInfoSinkBase &out, float f);
     void writeTriplet(Visit visit, const char *preStr, const char *inStr, const char *postStr);
     virtual void writeLayoutQualifier(TIntermTyped *variable);
     void writeInvariantQualifier(const TType &type);
     void writeVariableType(const TType &type);
     virtual bool writeVariablePrecision(TPrecision precision) = 0;
-    void writeFunctionParameters(const TIntermSequence &args);
+    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;
-    bool visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *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 visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node) override;
     bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
     bool visitLoop(Visit visit, TIntermLoop *node) override;
     bool visitBranch(Visit visit, TIntermBranch *node) override;
 
@@ -71,19 +71,20 @@ class TOutputGLSLBase : public TIntermTr
 
     ImmutableString hashFieldName(const TSymbol *containingStruct,
                                   const ImmutableString &fieldName);
     // 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) { return name; }
 
+    void declareStruct(const TStructure *structure);
+
   private:
     bool structDeclared(const TStructure *structure) const;
-    void declareStruct(const TStructure *structure);
 
     void declareInterfaceBlockLayout(const TInterfaceBlock *interfaceBlock);
     void declareInterfaceBlock(const TInterfaceBlock *interfaceBlock);
 
     void writeBuiltInFunctionTriplet(Visit visit, TOperator op, bool useEmulatedFunction);
 
     const char *mapQualifierToString(TQualifier qialifier);
 
--- a/gfx/angle/checkout/src/compiler/translator/OutputHLSL.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/OutputHLSL.cpp
@@ -10,27 +10,27 @@
 #include <cfloat>
 #include <stdio.h>
 
 #include "common/angleutils.h"
 #include "common/debug.h"
 #include "common/utilities.h"
 #include "compiler/translator/BuiltInFunctionEmulator.h"
 #include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
-#include "compiler/translator/FindSymbolNode.h"
 #include "compiler/translator/ImageFunctionHLSL.h"
 #include "compiler/translator/InfoSink.h"
-#include "compiler/translator/NodeSearch.h"
-#include "compiler/translator/RemoveSwitchFallThrough.h"
 #include "compiler/translator/StructureHLSL.h"
 #include "compiler/translator/TextureFunctionHLSL.h"
 #include "compiler/translator/TranslatorHLSL.h"
 #include "compiler/translator/UniformHLSL.h"
 #include "compiler/translator/UtilsHLSL.h"
 #include "compiler/translator/blocklayout.h"
+#include "compiler/translator/tree_ops/RemoveSwitchFallThrough.h"
+#include "compiler/translator/tree_util/FindSymbolNode.h"
+#include "compiler/translator/tree_util/NodeSearch.h"
 #include "compiler/translator/util.h"
 
 namespace sh
 {
 
 namespace
 {
 
@@ -1751,45 +1751,40 @@ bool OutputHLSL::visitFunctionDefinition
     ASSERT(mCurrentFunctionMetadata == nullptr);
 
     size_t index = mCallDag.findIndex(node->getFunction()->uniqueId());
     ASSERT(index != CallDAG::InvalidIndex);
     mCurrentFunctionMetadata = &mASTMetadataList[index];
 
     out << TypeString(node->getFunctionPrototype()->getType()) << " ";
 
-    TIntermSequence *parameters = node->getFunctionPrototype()->getSequence();
-
-    if (node->getFunction()->isMain())
+    const TFunction *func = node->getFunction();
+
+    if (func->isMain())
     {
         out << "gl_main(";
     }
     else
     {
-        out << DecorateFunctionIfNeeded(node->getFunction()) << DisambiguateFunctionName(parameters)
+        out << DecorateFunctionIfNeeded(func) << DisambiguateFunctionName(func)
             << (mOutputLod0Function ? "Lod0(" : "(");
     }
 
-    for (unsigned int i = 0; i < parameters->size(); i++)
+    size_t paramCount = func->getParamCount();
+    for (unsigned int i = 0; i < paramCount; i++)
     {
-        TIntermSymbol *symbol = (*parameters)[i]->getAsSymbolNode();
-
-        if (symbol)
+        const TVariable *param = func->getParam(i);
+        ensureStructDefined(param->getType());
+
+        writeParameter(param, out);
+
+        if (i < paramCount - 1)
         {
-            ensureStructDefined(symbol->getType());
-
-            writeParameter(symbol, out);
-
-            if (i < parameters->size() - 1)
-            {
-                out << ", ";
-            }
+            out << ", ";
         }
-        else
-            UNREACHABLE();
     }
 
     out << ")\n";
 
     mInsideFunction = true;
     // The function body node will output braces.
     node->getBody()->traverse(this);
     mInsideFunction = false;
@@ -1866,59 +1861,54 @@ bool OutputHLSL::visitDeclaration(Visit 
 }
 
 bool OutputHLSL::visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node)
 {
     // Do not do any translation
     return false;
 }
 
-bool OutputHLSL::visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node)
+void OutputHLSL::visitFunctionPrototype(TIntermFunctionPrototype *node)
 {
     TInfoSinkBase &out = getInfoSink();
 
-    ASSERT(visit == PreVisit);
     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 false;
+        return;
     }
 
-    TIntermSequence *arguments = node->getSequence();
-
-    TString name = DecorateFunctionIfNeeded(node->getFunction());
-    out << TypeString(node->getType()) << " " << name << DisambiguateFunctionName(arguments)
+    const TFunction *func = node->getFunction();
+
+    TString name = DecorateFunctionIfNeeded(func);
+    out << TypeString(node->getType()) << " " << name << DisambiguateFunctionName(func)
         << (mOutputLod0Function ? "Lod0(" : "(");
 
-    for (unsigned int i = 0; i < arguments->size(); i++)
+    size_t paramCount = func->getParamCount();
+    for (unsigned int i = 0; i < paramCount; i++)
     {
-        TIntermSymbol *symbol = (*arguments)[i]->getAsSymbolNode();
-        ASSERT(symbol != nullptr);
-
-        writeParameter(symbol, out);
-
-        if (i < arguments->size() - 1)
+        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;
     }
-
-    return false;
 }
 
 bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
 {
     TInfoSinkBase &out = getInfoSink();
 
     switch (node->getOp())
     {
@@ -2123,16 +2113,34 @@ bool OutputHLSL::visitAggregate(Visit vi
         case EOpBitfieldInsert:
         case EOpUaddCarry:
         case EOpUsubBorrow:
         case EOpUmulExtended:
         case EOpImulExtended:
             ASSERT(node->getUseEmulatedFunction());
             writeEmulatedFunctionTriplet(out, visit, node->getOp());
             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;
         default:
             UNREACHABLE();
     }
 
     return true;
 }
 
 void OutputHLSL::writeIfElse(TInfoSinkBase &out, TIntermIfElse *node)
@@ -2637,32 +2645,23 @@ void OutputHLSL::outputLineDirective(TIn
         {
             out << " \"" << mSourcePath << "\"";
         }
 
         out << "\n";
     }
 }
 
-void OutputHLSL::writeParameter(const TIntermSymbol *symbol, TInfoSinkBase &out)
+void OutputHLSL::writeParameter(const TVariable *param, TInfoSinkBase &out)
 {
-    TQualifier qualifier = symbol->getQualifier();
-    const TType &type    = symbol->getType();
-    const TVariable &variable = symbol->variable();
-    TString nameStr;
-
-    if (variable.symbolType() ==
-        SymbolType::Empty)  // HLSL demands named arguments, also for prototypes
-    {
-        nameStr = "x" + str(mUniqueIndex++);
-    }
-    else
-    {
-        nameStr = DecorateVariableIfNeeded(variable);
-    }
+    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 != EvqOut && qualifier != EvqInOut);
             out << "const uint " << nameStr << ArrayString(type);
--- a/gfx/angle/checkout/src/compiler/translator/OutputHLSL.h
+++ b/gfx/angle/checkout/src/compiler/translator/OutputHLSL.h
@@ -11,17 +11,17 @@
 #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/IntermTraverse.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
 
 class BuiltInFunctionEmulator;
 
 namespace sh
 {
 class StructureHLSL;
 class TextureFunctionHLSL;
 class TSymbolTable;
@@ -88,17 +88,17 @@ class OutputHLSL : public TIntermTravers
     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;
-    bool visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *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 *node) override;
     bool visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node) override;
     bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
     bool visitLoop(Visit visit, TIntermLoop *) override;
     bool visitBranch(Visit visit, TIntermBranch *) override;
 
@@ -107,17 +107,17 @@ class OutputHLSL : public TIntermTravers
     // 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 TIntermSymbol *symbol, TInfoSinkBase &out);
+    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);
--- a/gfx/angle/checkout/src/compiler/translator/OutputTree.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/OutputTree.cpp
@@ -1,16 +1,16 @@
 //
 // Copyright (c) 2002-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/IntermTraverse.h"
 #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)
@@ -26,38 +26,44 @@ void OutputFunction(TInfoSinkBase &out, 
 //     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) {}
+    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;
-    bool visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *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 visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *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;
@@ -74,46 +80,46 @@ void OutputTreeText(TInfoSinkBase &out, 
 //
 // 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, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
 
     if (node->variable().symbolType() == SymbolType::Empty)
     {
         mOut << "''";
     }
     else
     {
         mOut << "'" << node->getName() << "' ";
     }
     mOut << "(symbol id " << node->uniqueId().get() << ") ";
     mOut << "(" << node->getCompleteString() << ")";
     mOut << "\n";
 }
 
 bool TOutputTraverser::visitSwizzle(Visit visit, TIntermSwizzle *node)
 {
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
     mOut << "vector swizzle (";
     node->writeOffsetsAsXYZW(&mOut);
     mOut << ")";
 
     mOut << " (" << node->getCompleteString() << ")";
     mOut << "\n";
     return true;
 }
 
 bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary *node)
 {
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
 
     switch (node->getOp())
     {
         case EOpComma:
             mOut << "comma";
             break;
         case EOpAssign:
             mOut << "move second child to first child";
@@ -265,17 +271,17 @@ bool TOutputTraverser::visitBinary(Visit
     // 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, mDepth + 1);
+        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();
@@ -289,17 +295,17 @@ bool TOutputTraverser::visitBinary(Visit
         return false;
     }
 
     return true;
 }
 
 bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node)
 {
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
 
     switch (node->getOp())
     {
         // 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;
@@ -343,42 +349,47 @@ bool TOutputTraverser::visitUnary(Visit 
 
     mOut << "\n";
 
     return true;
 }
 
 bool TOutputTraverser::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
 {
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
     mOut << "Function Definition:\n";
-    mOut << "\n";
     return true;
 }
 
 bool TOutputTraverser::visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node)
 {
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
     mOut << "Invariant Declaration:\n";
     return true;
 }
 
-bool TOutputTraverser::visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node)
+void TOutputTraverser::visitFunctionPrototype(TIntermFunctionPrototype *node)
 {
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
     OutputFunction(mOut, "Function Prototype", node->getFunction());
     mOut << " (" << node->getCompleteString() << ")";
     mOut << "\n";
-
-    return true;
+    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().getCompleteString()
+             << ")";
+    }
 }
 
 bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
 {
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
 
     if (node->getOp() == EOpNull)
     {
         mOut.prefix(SH_ERROR);
         mOut << "node is still EOpNull!\n";
         return true;
     }
 
@@ -440,108 +451,108 @@ bool TOutputTraverser::visitAggregate(Vi
 
     mOut << "\n";
 
     return true;
 }
 
 bool TOutputTraverser::visitBlock(Visit visit, TIntermBlock *node)
 {
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
     mOut << "Code block\n";
 
     return true;
 }
 
 bool TOutputTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
 {
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
     mOut << "Declaration\n";
 
     return true;
 }
 
 bool TOutputTraverser::visitTernary(Visit visit, TIntermTernary *node)
 {
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
 
     mOut << "Ternary selection";
     mOut << " (" << node->getCompleteString() << ")\n";
 
-    ++mDepth;
+    ++mIndentDepth;
 
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
     mOut << "Condition\n";
     node->getCondition()->traverse(this);
 
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
     if (node->getTrueExpression())
     {
         mOut << "true case\n";
         node->getTrueExpression()->traverse(this);
     }
     if (node->getFalseExpression())
     {
-        OutputTreeText(mOut, node, mDepth);
+        OutputTreeText(mOut, node, getCurrentIndentDepth());
         mOut << "false case\n";
         node->getFalseExpression()->traverse(this);
     }
 
-    --mDepth;
+    --mIndentDepth;
 
     return false;
 }
 
 bool TOutputTraverser::visitIfElse(Visit visit, TIntermIfElse *node)
 {
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
 
     mOut << "If test\n";
 
-    ++mDepth;
+    ++mIndentDepth;
 
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
     mOut << "Condition\n";
     node->getCondition()->traverse(this);
 
-    OutputTreeText(mOut, node, mDepth);
+    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, mDepth);
+        OutputTreeText(mOut, node, getCurrentIndentDepth());
         mOut << "false case\n";
         node->getFalseBlock()->traverse(this);
     }
 
-    --mDepth;
+    --mIndentDepth;
 
     return false;
 }
 
 bool TOutputTraverser::visitSwitch(Visit visit, TIntermSwitch *node)
 {
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
 
     mOut << "Switch\n";
 
     return true;
 }
 
 bool TOutputTraverser::visitCase(Visit visit, TIntermCase *node)
 {
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
 
     if (node->getCondition() == nullptr)
     {
         mOut << "Default\n";
     }
     else
     {
         mOut << "Case\n";
@@ -551,17 +562,17 @@ bool TOutputTraverser::visitCase(Visit v
 }
 
 void TOutputTraverser::visitConstantUnion(TIntermConstantUnion *node)
 {
     size_t size = node->getType().getObjectSize();
 
     for (size_t i = 0; i < size; i++)
     {
-        OutputTreeText(mOut, node, mDepth);
+        OutputTreeText(mOut, node, getCurrentIndentDepth());
         switch (node->getConstantValue()[i].getType())
         {
             case EbtBool:
                 if (node->getConstantValue()[i].getBConst())
                     mOut << "true";
                 else
                     mOut << "false";
 
@@ -592,62 +603,62 @@ void TOutputTraverser::visitConstantUnio
                 mOut << "Unknown constant\n";
                 break;
         }
     }
 }
 
 bool TOutputTraverser::visitLoop(Visit visit, TIntermLoop *node)
 {
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
 
     mOut << "Loop with condition ";
     if (node->getType() == ELoopDoWhile)
         mOut << "not ";
     mOut << "tested first\n";
 
-    ++mDepth;
+    ++mIndentDepth;
 
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
     if (node->getCondition())
     {
         mOut << "Loop Condition\n";
         node->getCondition()->traverse(this);
     }
     else
     {
         mOut << "No loop condition\n";
     }
 
-    OutputTreeText(mOut, node, mDepth);
+    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, mDepth);
+        OutputTreeText(mOut, node, getCurrentIndentDepth());
         mOut << "Loop Terminal Expression\n";
         node->getExpression()->traverse(this);
     }
 
-    --mDepth;
+    --mIndentDepth;
 
     return false;
 }
 
 bool TOutputTraverser::visitBranch(Visit visit, TIntermBranch *node)
 {
-    OutputTreeText(mOut, node, mDepth);
+    OutputTreeText(mOut, node, getCurrentIndentDepth());
 
     switch (node->getFlowOp())
     {
         case EOpKill:
             mOut << "Branch: Kill";
             break;
         case EOpBreak:
             mOut << "Branch: Break";
@@ -661,19 +672,19 @@ bool TOutputTraverser::visitBranch(Visit
         default:
             mOut << "Branch: Unknown Branch";
             break;
     }
 
     if (node->getExpression())
     {
         mOut << " with expression\n";
-        ++mDepth;
+        ++mIndentDepth;
         node->getExpression()->traverse(this);
-        --mDepth;
+        --mIndentDepth;
     }
     else
     {
         mOut << "\n";
     }
 
     return false;
 }
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ParamType.h
+++ /dev/null
@@ -1,102 +0,0 @@
-//
-// 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.
-//
-// ParamType:
-//   Helper type for built-in function emulator tables. Defines types for parameters.
-
-#ifndef COMPILER_TRANSLATOR_PARAMTYPE_H_
-#define COMPILER_TRANSLATOR_PARAMTYPE_H_
-
-#include "common/angleutils.h"
-#include "compiler/translator/BaseTypes.h"
-
-namespace sh
-{
-
-enum class ParamType : uint8_t
-{
-    Void,
-    Bool1,
-    Bool2,
-    Bool3,
-    Bool4,
-    Float1,
-    Float2,
-    Float3,
-    Float4,
-    Int1,
-    Int2,
-    Int3,
-    Int4,
-    Mat2,
-    Mat3,
-    Mat4,
-    Uint1,
-    Uint2,
-    Uint3,
-    Uint4,
-    Last,
-};
-
-struct ParamTypeInfo
-{
-    ParamType self;
-    TBasicType basicType;
-    int primarySize;
-    int secondarySize;
-};
-
-constexpr ParamTypeInfo g_ParamTypeInfo[] = {
-    {ParamType::Void, EbtVoid, 1, 1},    {ParamType::Bool1, EbtBool, 1, 1},
-    {ParamType::Bool2, EbtBool, 2, 1},   {ParamType::Bool3, EbtBool, 3, 1},
-    {ParamType::Bool4, EbtBool, 4, 1},   {ParamType::Float1, EbtFloat, 1, 1},
-    {ParamType::Float2, EbtFloat, 2, 1}, {ParamType::Float3, EbtFloat, 3, 1},
-    {ParamType::Float4, EbtFloat, 4, 1}, {ParamType::Int1, EbtInt, 1, 1},
-    {ParamType::Int2, EbtInt, 2, 1},     {ParamType::Int3, EbtInt, 3, 1},
-    {ParamType::Int4, EbtInt, 4, 1},     {ParamType::Mat2, EbtFloat, 2, 2},
-    {ParamType::Mat3, EbtFloat, 3, 3},   {ParamType::Mat4, EbtFloat, 4, 4},
-    {ParamType::Uint1, EbtUInt, 1, 1},   {ParamType::Uint2, EbtUInt, 2, 1},
-    {ParamType::Uint3, EbtUInt, 3, 1},   {ParamType::Uint4, EbtUInt, 4, 1},
-};
-
-constexpr size_t ParamTypeIndex(ParamType paramType)
-{
-    return static_cast<size_t>(paramType);
-}
-
-constexpr size_t NumParamTypes()
-{
-    return ParamTypeIndex(ParamType::Last);
-}
-
-static_assert(ArraySize(g_ParamTypeInfo) == NumParamTypes(), "Invalid array size");
-
-constexpr TBasicType GetBasicType(ParamType paramType)
-{
-    return g_ParamTypeInfo[ParamTypeIndex(paramType)].basicType;
-}
-
-constexpr int GetPrimarySize(ParamType paramType)
-{
-    return g_ParamTypeInfo[ParamTypeIndex(paramType)].primarySize;
-}
-
-constexpr int GetSecondarySize(ParamType paramType)
-{
-    return g_ParamTypeInfo[ParamTypeIndex(paramType)].secondarySize;
-}
-
-constexpr bool SameParamType(ParamType paramType,
-                             TBasicType basicType,
-                             int primarySize,
-                             int secondarySize)
-{
-    return GetBasicType(paramType) == basicType && primarySize == GetPrimarySize(paramType) &&
-           secondarySize == GetSecondarySize(paramType);
-}
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_PARAMTYPE_H_
--- a/gfx/angle/checkout/src/compiler/translator/ParseContext.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/ParseContext.cpp
@@ -7,64 +7,38 @@
 #include "compiler/translator/ParseContext.h"
 
 #include <stdarg.h>
 #include <stdio.h>
 
 #include "common/mathutil.h"
 #include "compiler/preprocessor/SourceLocation.h"
 #include "compiler/translator/Declarator.h"
-#include "compiler/translator/IntermNode_util.h"
+#include "compiler/translator/ParseContext_autogen.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;
 
-constexpr const ImmutableString kTexelFetchOffsetName("texelFetchOffsetName");
-constexpr const ImmutableString kTextureLodOffsetName("textureLodOffset");
-constexpr const ImmutableString kTextureProjLodOffsetName("textureProjLodOffset");
-constexpr const ImmutableString kTextureGradOffsetName("textureGradOffset");
-constexpr const ImmutableString kTextureProjGradOffsetName("textureProjGradOffset");
-constexpr const ImmutableString kTextureOffsetName("textureOffset");
-constexpr const ImmutableString kTextureProjOffsetName("textureProjOffset");
-constexpr const ImmutableString kTextureGatherName("textureGather");
-constexpr const ImmutableString kTextureGatherOffsetName("textureGatherOffset");
-
-constexpr const std::array<ImmutableString, 8> kAtomicBuiltin = {
-    {ImmutableString("atomicAdd"), ImmutableString("atomicMin"), ImmutableString("atomicMax"),
-     ImmutableString("atomicAnd"), ImmutableString("atomicOr"), ImmutableString("atomicXor"),
-     ImmutableString("atomicExchange"), ImmutableString("atomicCompSwap")}};
-
-bool IsAtomicBuiltin(const ImmutableString &name)
-{
-    for (size_t i = 0; i < kAtomicBuiltin.size(); ++i)
-    {
-        if (name == kAtomicBuiltin[i])
-        {
-            return true;
-        }
-    }
-    return false;
-}
-
 bool ContainsSampler(const TStructure *structType);
 
 bool ContainsSampler(const TType &type)
 {
     if (IsSampler(type.getBasicType()))
     {
         return true;
     }
@@ -217,19 +191,16 @@ TParseContext::TParseContext(TSymbolTabl
       mDiagnostics(diagnostics),
       mDirectiveHandler(ext,
                         *mDiagnostics,
                         mShaderVersion,
                         mShaderType,
                         resources.WEBGL_debug_shader_precision == 1),
       mPreprocessor(mDiagnostics, &mDirectiveHandler, pp::PreprocessorSettings()),
       mScanner(nullptr),
-      mUsesFragData(false),
-      mUsesFragColor(false),
-      mUsesSecondaryOutputs(false),
       mMinProgramTexelOffset(resources.MinProgramTexelOffset),
       mMaxProgramTexelOffset(resources.MaxProgramTexelOffset),
       mMinProgramTextureGatherOffset(resources.MinProgramTextureGatherOffset),
       mMaxProgramTextureGatherOffset(resources.MaxProgramTextureGatherOffset),
       mComputeShaderLocalSizeDeclared(false),
       mComputeShaderLocalSize(-1),
       mNumViews(-1),
       mMaxNumViews(resources.MaxViewsOVR),
@@ -240,18 +211,17 @@ TParseContext::TParseContext(TSymbolTabl
       mMaxAtomicCounterBindings(resources.MaxAtomicCounterBindings),
       mMaxShaderStorageBufferBindings(resources.MaxShaderStorageBufferBindings),
       mDeclaringFunction(false),
       mGeometryShaderInputPrimitiveType(EptUndefined),
       mGeometryShaderOutputPrimitiveType(EptUndefined),
       mGeometryShaderInvocations(0),
       mGeometryShaderMaxVertices(-1),
       mMaxGeometryShaderInvocations(resources.MaxGeometryShaderInvocations),
-      mMaxGeometryShaderMaxVertices(resources.MaxGeometryOutputVertices),
-      mGlInVariableWithArraySize(nullptr)
+      mMaxGeometryShaderMaxVertices(resources.MaxGeometryOutputVertices)
 {
 }
 
 TParseContext::~TParseContext()
 {
 }
 
 bool TParseContext::parseVectorFields(const TSourceLoc &line,
@@ -464,35 +434,63 @@ void TParseContext::checkPrecisionSpecif
                 {
                     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)
 {
-    TIntermSymbol *symNode      = node->getAsSymbolNode();
-    TIntermBinary *binaryNode   = node->getAsBinaryNode();
     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:
@@ -603,50 +601,42 @@ bool TParseContext::checkCanBeLValue(con
                 message += getBasicString(node->getBasicType());
             }
             else if (node->getMemoryQualifier().readonly)
             {
                 message = "can't modify a readonly variable";
             }
     }
 
-    if (message.empty() && binaryNode == 0 && symNode == 0)
-    {
-        error(line, "l-value required", op);
-
-        return false;
-    }
-
-    //
-    // Everything else is okay, no error.
-    //
-    if (message.empty())
+    ASSERT(binaryNode == nullptr && swizzleNode == nullptr);
+    TIntermSymbol *symNode = node->getAsSymbolNode();
+    if (message.empty() && symNode != nullptr)
+    {
+        symbolTable.markStaticWrite(symNode->variable());
         return true;
-
-    //
-    // If we get here, we have an error and a message.
-    //
-    if (symNode)
-    {
-        // Symbol inside an expression can't be nameless.
-        ASSERT(symNode->variable().symbolType() != SymbolType::Empty);
-
-        const ImmutableString &symbol = symNode->getName();
-        std::stringstream reasonStream;
-        reasonStream << "l-value required (" << message << " \"" << symbol << "\")";
-        std::string reason = reasonStream.str();
-        error(line, reason.c_str(), op);
-    }
-    else
-    {
-        std::stringstream reasonStream;
-        reasonStream << "l-value required (" << message << ")";
-        std::string reason = reasonStream.str();
-        error(line, reason.c_str(), op);
-    }
+    }
+
+    std::stringstream reasonStream;
+    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)
 {
@@ -721,16 +711,17 @@ bool TParseContext::checkConstructorArgu
     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;
@@ -1164,17 +1155,17 @@ bool TParseContext::declareVariable(cons
                   identifier);
             return false;
         }
     }
 
     if (needsReservedCheck && !checkIsNotReserved(line, identifier))
         return false;
 
-    if (!symbolTable.declareVariable(*variable))
+    if (!symbolTable.declare(*variable))
     {
         error(line, "redefinition", identifier);
         return false;
     }
 
     if (!checkIsNonVoid(line, identifier, type->getBasicType()))
         return false;
 
@@ -1695,27 +1686,32 @@ void TParseContext::checkYuvIsNotSpecifi
     }
 }
 
 void TParseContext::functionCallRValueLValueErrorCheck(const TFunction *fnCandidate,
                                                        TIntermAggregate *fnCall)
 {
     for (size_t i = 0; i < fnCandidate->getParamCount(); ++i)
     {
-        TQualifier qual = fnCandidate->getParam(i).type->getQualifier();
+        TQualifier qual        = fnCandidate->getParam(i)->getType().getQualifier();
         TIntermTyped *argument = (*(fnCall->getSequence()))[i]->getAsTyped();
-        if (!IsImage(argument->getBasicType()) && (IsQualifierUnspecified(qual) || qual == EvqIn ||
-                                                   qual == EvqInOut || qual == EvqConstReadOnly))
-        {
-            if (argument->getMemoryQualifier().writeonly)
+        bool argumentIsRead = (IsQualifierUnspecified(qual) || qual == EvqIn || qual == EvqInOut ||
+                               qual == EvqConstReadOnly);
+        if (argumentIsRead)
+        {
+            markStaticReadIfSymbol(argument);
+            if (!IsImage(argument->getBasicType()))
             {
-                error(argument->getLine(),
-                      "Writeonly value cannot be passed for 'in' or 'inout' parameters.",
-                      fnCall->functionName());
-                return;
+                if (argument->getMemoryQualifier().writeonly)
+                {
+                    error(argument->getLine(),
+                          "Writeonly value cannot be passed for 'in' or 'inout' parameters.",
+                          fnCall->functionName());
+                    return;
+                }
             }
         }
         if (qual == EvqOut || qual == EvqInOut)
         {
             if (!checkCanBeLValue(argument->getLine(), "assign", argument))
             {
                 error(argument->getLine(),
                       "Constant value cannot be passed for 'out' or 'inout' parameters.",
@@ -1826,50 +1822,19 @@ const TVariable *TParseContext::getNamed
 
     const TVariable *variable = static_cast<const TVariable *>(symbol);
 
     if (variable->extension() != TExtension::UNDEFINED)
     {
         checkCanUseExtension(location, variable->extension());
     }
 
-    // Reject shaders using both gl_FragData and gl_FragColor
-    TQualifier qualifier = variable->getType().getQualifier();
-    if (qualifier == EvqFragData || qualifier == EvqSecondaryFragDataEXT)
-    {
-        mUsesFragData = true;
-    }
-    else if (qualifier == EvqFragColor || qualifier == EvqSecondaryFragColorEXT)
-    {
-        mUsesFragColor = true;
-    }
-    if (qualifier == EvqSecondaryFragDataEXT || qualifier == EvqSecondaryFragColorEXT)
-    {
-        mUsesSecondaryOutputs = true;
-    }
-
-    // This validation is not quite correct - it's only an error to write to
-    // both FragData and FragColor. For simplicity, and because users shouldn't
-    // be rewarded for reading from undefined varaibles, return an error
-    // if they are both referenced, rather than assigned.
-    if (mUsesFragData && mUsesFragColor)
-    {
-        const char *errorMessage = "cannot use both gl_FragData and gl_FragColor";
-        if (mUsesSecondaryOutputs)
-        {
-            errorMessage =
-                "cannot use both output variable sets (gl_FragData, gl_SecondaryFragDataEXT)"
-                " and (gl_FragColor, gl_SecondaryFragColorEXT)";
-        }
-        error(location, errorMessage, name);
-    }
-
     // GLSL ES 3.1 Revision 4, 7.1.3 Compute Shader Special Variables
     if (getShaderType() == GL_COMPUTE_SHADER && !mComputeShaderLocalSizeDeclared &&
-        qualifier == EvqWorkGroupSize)
+        variable->getType().getQualifier() == EvqWorkGroupSize)
     {
         error(location,
               "It is an error to use gl_WorkGroupSize before declaring the local group size",
               "gl_WorkGroupSize");
     }
     return variable;
 }
 
@@ -1910,18 +1875,18 @@ TIntermTyped *TParseContext::parseVariab
 
         TType type(variableType);
         type.setQualifier(EvqConst);
         node = new TIntermConstantUnion(constArray, type);
     }
     else if ((mGeometryShaderInputPrimitiveType != EptUndefined) &&
              (variableType.getQualifier() == EvqPerVertexIn))
     {
-        ASSERT(mGlInVariableWithArraySize != nullptr);
-        node = new TIntermSymbol(mGlInVariableWithArraySize);
+        ASSERT(symbolTable.getGlInVariableWithArraySize() != nullptr);
+        node = new TIntermSymbol(symbolTable.getGlInVariableWithArraySize());
     }
     else
     {
         node = new TIntermSymbol(variable);
     }
     ASSERT(node != nullptr);
     node->setLine(location);
     return node;
@@ -2026,16 +1991,17 @@ bool TParseContext::executeInitializer(c
             {
                 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)
@@ -2068,18 +2034,29 @@ TIntermNode *TParseContext::addLoop(TLoo
                                     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)
         {
             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 ||
@@ -2116,31 +2093,42 @@ TIntermNode *TParseContext::addLoop(TLoo
     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,
@@ -2378,19 +2366,19 @@ void TParseContext::checkGeometryShaderI
     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(mGlInVariableWithArraySize != nullptr);
+                ASSERT(symbolTable.getGlInVariableWithArraySize() != nullptr);
                 type->sizeOutermostUnsizedArray(
-                    mGlInVariableWithArraySize->getType().getOutermostArraySize());
+                    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.
                 error(location,
                       "Missing a valid input primitive declaration before declaring an unsized "
@@ -2850,27 +2838,17 @@ bool TParseContext::checkPrimitiveTypeMa
             UNREACHABLE();
             return false;
     }
 }
 
 void TParseContext::setGeometryShaderInputArraySize(unsigned int inputArraySize,
                                                     const TSourceLoc &line)
 {
-    if (mGlInVariableWithArraySize == nullptr)
-    {
-        const TSymbol *glPerVertex = symbolTable.findBuiltIn(ImmutableString("gl_PerVertex"), 310);
-        const TInterfaceBlock *glPerVertexBlock = static_cast<const TInterfaceBlock *>(glPerVertex);
-        TType *glInType = new TType(glPerVertexBlock, EvqPerVertexIn, TLayoutQualifier::Create());
-        glInType->makeArray(inputArraySize);
-        mGlInVariableWithArraySize =
-            new TVariable(&symbolTable, ImmutableString("gl_in"), glInType, SymbolType::BuiltIn,
-                          TExtension::EXT_geometry_shader);
-    }
-    else if (mGlInVariableWithArraySize->getType().getOutermostArraySize() != inputArraySize)
+    if (!symbolTable.setGlInArraySize(inputArraySize))
     {
         error(line,
               "Array size or input primitive declaration doesn't match the size of earlier sized "
               "array inputs.",
               "layout");
     }
 }
 
@@ -3175,57 +3153,41 @@ TIntermFunctionPrototype *TParseContext:
 {
     checkIsNotReserved(location, function.name());
 
     TIntermFunctionPrototype *prototype = new TIntermFunctionPrototype(&function);
     prototype->setLine(location);
 
     for (size_t i = 0; i < function.getParamCount(); i++)
     {
-        const TConstParameter &param = function.getParam(i);
-
-        TIntermSymbol *symbol = nullptr;
+        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.name != nullptr)
-        {
-            TVariable *variable =
-                new TVariable(&symbolTable, param.name, param.type, SymbolType::UserDefined);
-            symbol = new TIntermSymbol(variable);
-            // Insert the parameter in the symbol table.
+        if (param->symbolType() != SymbolType::Empty)
+        {
             if (insertParametersToSymbolTable)
             {
-                if (!symbolTable.declareVariable(variable))
+                if (!symbolTable.declare(const_cast<TVariable *>(param)))
                 {
-                    error(location, "redefinition", param.name);
+                    error(location, "redefinition", param->name());
                 }
             }
             // Unsized type of a named parameter should have already been checked and sanitized.
-            ASSERT(!param.type->isUnsizedArray());
+            ASSERT(!param->getType().isUnsizedArray());
         }
         else
         {
-            if (param.type->isUnsizedArray())
+            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.
             }
         }
-        if (!symbol)
-        {
-            // The parameter had no name or declaring the symbol failed - either way, add a nameless
-            // symbol.
-            TVariable *emptyVariable =
-                new TVariable(&symbolTable, ImmutableString(""), param.type, SymbolType::Empty);
-            symbol = new TIntermSymbol(emptyVariable);
-        }
-        symbol->setLine(location);
-        prototype->appendParameter(symbol);
     }
     return prototype;
 }
 
 TIntermFunctionPrototype *TParseContext::addFunctionPrototypeDeclaration(
     const TFunction &parsedFunction,
     const TSourceLoc &location)
 {
@@ -3308,18 +3270,18 @@ TFunction *TParseContext::parseFunctionD
     //
     // 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)
     {
-        auto &param = function->getParam(i);
-        if (param.type->isStructSpecifier())
+        const TVariable *param = function->getParam(i);
+        if (param->getType().isStructSpecifier())
         {
             // ESSL 3.00.6 section 12.10.
             error(location, "Function parameter type cannot be a structure definition",
                   function->name());
         }
     }
 
     if (getShaderVersion() >= 300)
@@ -3355,22 +3317,22 @@ TFunction *TParseContext::parseFunctionD
     {
         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).type->getQualifier() !=
-                function->getParam(i).type->getQualifier())
+            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).type->getQualifierString());
+                      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)
@@ -3787,17 +3749,17 @@ TIntermDeclaration *TParseContext::addIn
             // 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);
         }
     }
 
     TInterfaceBlock *interfaceBlock = new TInterfaceBlock(
         &symbolTable, blockName, fieldList, blockLayoutQualifier, SymbolType::UserDefined);
-    if (!symbolTable.declareInterfaceBlock(interfaceBlock))
+    if (!symbolTable.declare(interfaceBlock))
     {
         error(nameLine, "redefinition of an interface block name", blockName);
     }
 
     TType *interfaceBlockType =
         new TType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier);
     if (arrayIndex != nullptr)
     {
@@ -3821,29 +3783,29 @@ TIntermDeclaration *TParseContext::addIn
 
             // set parent pointer of the field variable
             fieldType->setInterfaceBlock(interfaceBlock);
 
             fieldType->setQualifier(typeQualifier.qualifier);
 
             TVariable *fieldVariable =
                 new TVariable(&symbolTable, field->name(), fieldType, SymbolType::UserDefined);
-            if (!symbolTable.declareVariable(fieldVariable))
+            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.declareVariable(instanceVariable))
+        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();
@@ -4058,16 +4020,17 @@ TIntermTyped *TParseContext::addIndexExp
 
             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,
@@ -4773,17 +4736,17 @@ TTypeSpecifierNonArray TParseContext::ad
 
     // 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.declareStructType(structure))
+        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++)
     {
@@ -4835,22 +4798,23 @@ TIntermSwitch *TParseContext::addSwitch(
         init->isVector())
     {
         error(init->getLine(), "init-expression in a switch statement must be a scalar integer",
               "switch");
         return nullptr;
     }
 
     ASSERT(statementList);
-    if (!ValidateSwitchStatementList(switchType, mShaderVersion, mDiagnostics, statementList, loc))
+    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)
@@ -4890,17 +4854,18 @@ TIntermCase *TParseContext::addDefault(c
     }
     TIntermCase *node = new TIntermCase(nullptr);
     node->setLine(loc);
     return node;
 }
 
 TIntermTyped *TParseContext::createUnaryMath(TOperator op,
                                              TIntermTyped *child,
-                                             const TSourceLoc &loc)
+                                             const TSourceLoc &loc,
+                                             const TFunction *func)
 {
     ASSERT(child != nullptr);
 
     switch (op)
     {
         case EOpLogicalNot:
             if (child->getBasicType() != EbtBool || child->isMatrix() || child->isArray() ||
                 child->isVector())
@@ -4937,26 +4902,27 @@ TIntermTyped *TParseContext::createUnary
     }
 
     if (child->getMemoryQualifier().writeonly)
     {
         unaryOpError(loc, GetOperatorString(op), child->getCompleteString());
         return nullptr;
     }
 
-    TIntermUnary *node = new TIntermUnary(op, child);
+    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);
+    TIntermTyped *node = createUnaryMath(op, child, loc, nullptr);
     if (node == nullptr)
     {
         return child;
     }
     return node;
 }
 
 TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op,
@@ -5340,16 +5306,19 @@ TIntermTyped *TParseContext::addBinaryMa
         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)
@@ -5375,51 +5344,49 @@ TIntermTyped *TParseContext::addBinaryMa
         binaryOpError(loc, GetOperatorString(op), left->getCompleteString(),
                       right->getCompleteString());
         node = CreateBoolNode(false);
         node->setLine(loc);
     }
     return node;
 }
 
-TIntermBinary *TParseContext::createAssign(TOperator op,
-                                           TIntermTyped *left,
-                                           TIntermTyped *right,
-                                           const TSourceLoc &loc)
-{
-    if (binaryOpCommonCheck(op, left, right, loc))
-    {
-        if (op == EOpMulAssign)
-        {
-            op = TIntermBinary::GetMulAssignOpBasedOnOperands(left->getType(), right->getType());
-            if (!isMultiplicationTypeCombinationValid(op, left->getType(), right->getType()))
-            {
-                return nullptr;
-            }
-        }
-        TIntermBinary *node = new TIntermBinary(op, left, right);
-        node->setLine(loc);
-
-        return node;
-    }
-    return nullptr;
-}
-
 TIntermTyped *TParseContext::addAssign(TOperator op,
                                        TIntermTyped *left,
                                        TIntermTyped *right,
                                        const TSourceLoc &loc)
 {
     checkCanBeLValue(loc, "assign", left);
-    TIntermTyped *node = createAssign(op, left, right, loc);
+    TIntermBinary *node = nullptr;
+    if (binaryOpCommonCheck(op, left, right, 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->getCompleteString(), right->getCompleteString());
         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:
@@ -5430,16 +5397,19 @@ TIntermTyped *TParseContext::addComma(TI
          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)
     {
@@ -5475,54 +5445,63 @@ TIntermBranch *TParseContext::addBranch(
 }
 
 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)
 {
     ASSERT(functionCall->getOp() == EOpCallBuiltInFunction);
-    const ImmutableString &name = functionCall->getFunction()->name();
-    bool isTextureGather        = name == kTextureGatherName;
-    bool isTextureGatherOffset  = name == kTextureGatherOffsetName;
-    if (isTextureGather || isTextureGatherOffset)
-    {
+    const TFunction *func = functionCall->getFunction();
+    if (BuiltInGroup::isTextureGather(func))
+    {
+        bool isTextureGatherOffset = BuiltInGroup::isTextureGatherOffset(func);
         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 ((isTextureGather && arguments->size() == 3u) ||
+                if ((!isTextureGatherOffset && arguments->size() == 3u) ||
                     (isTextureGatherOffset && arguments->size() == 4u))
                 {
                     componentNode = arguments->back();
                 }
                 break;
             case EbtSamplerCube:
             case EbtISamplerCube:
             case EbtUSamplerCube:
@@ -5542,50 +5521,49 @@ void TParseContext::checkTextureGather(T
         }
         if (componentNode)
         {
             const TIntermConstantUnion *componentConstantUnion =
                 componentNode->getAsConstantUnion();
             if (componentNode->getAsTyped()->getQualifier() != EvqConst || !componentConstantUnion)
             {
                 error(functionCall->getLine(), "Texture component must be a constant expression",
-                      name);
+                      func->name());
             }
             else
             {
                 int component = componentConstantUnion->getIConst(0);
                 if (component < 0 || component > 3)
                 {
-                    error(functionCall->getLine(), "Component must be in the range [0;3]", name);
+                    error(functionCall->getLine(), "Component must be in the range [0;3]",
+                          func->name());
                 }
             }
         }
     }
 }
 
 void TParseContext::checkTextureOffsetConst(TIntermAggregate *functionCall)
 {
     ASSERT(functionCall->getOp() == EOpCallBuiltInFunction);
-    const ImmutableString &name            = functionCall->getFunction()->name();
+    const TFunction *func                  = functionCall->getFunction();
     TIntermNode *offset        = nullptr;
     TIntermSequence *arguments = functionCall->getSequence();
     bool useTextureGatherOffsetConstraints = false;
-    if (name == kTexelFetchOffsetName || name == kTextureLodOffsetName ||
-        name == kTextureProjLodOffsetName || name == kTextureGradOffsetName ||
-        name == kTextureProjGradOffsetName)
+    if (BuiltInGroup::isTextureOffsetNoBias(func))
     {
         offset = arguments->back();
     }
-    else if (name == kTextureOffsetName || name == kTextureProjOffsetName)
-    {
-        // A bias parameter might follow the offset parameter.
+    else if (BuiltInGroup::isTextureOffsetBias(func))
+    {
+        // A bias parameter follows the offset parameter.
         ASSERT(arguments->size() >= 3);
         offset = (*arguments)[2];
     }
-    else if (name == kTextureGatherOffsetName)
+    else if (BuiltInGroup::isTextureGatherOffset(func))
     {
         ASSERT(arguments->size() >= 3u);
         const TIntermTyped *sampler = arguments->front()->getAsTyped();
         ASSERT(sampler != nullptr);
         switch (sampler->getBasicType())
         {
             case EbtSampler2D:
             case EbtISampler2D:
@@ -5605,17 +5583,18 @@ void TParseContext::checkTextureOffsetCo
         }
         useTextureGatherOffsetConstraints = true;
     }
     if (offset != nullptr)
     {
         TIntermConstantUnion *offsetConstantUnion = offset->getAsConstantUnion();
         if (offset->getAsTyped()->getQualifier() != EvqConst || !offsetConstantUnion)
         {
-            error(functionCall->getLine(), "Texture offset must be a constant expression", name);
+            error(functionCall->getLine(), "Texture offset must be a constant expression",
+                  func->name());
         }
         else
         {
             ASSERT(offsetConstantUnion->getBasicType() == EbtInt);
             size_t size                  = offsetConstantUnion->getType().getObjectSize();
             const TConstantUnion *values = offsetConstantUnion->getConstantValue();
             int minOffsetValue = useTextureGatherOffsetConstraints ? mMinProgramTextureGatherOffset
                                                                    : mMinProgramTexelOffset;
@@ -5635,18 +5614,18 @@ void TParseContext::checkTextureOffsetCo
             }
         }
     }
 }
 
 void TParseContext::checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall)
 {
     ASSERT(functionCall->getOp() == EOpCallBuiltInFunction);
-    const ImmutableString &functionName = functionCall->getFunction()->name();
-    if (IsAtomicBuiltin(functionName))
+    const TFunction *func = functionCall->getFunction();
+    if (BuiltInGroup::isAtomicMemory(func))
     {
         TIntermSequence *arguments = functionCall->getSequence();
         TIntermTyped *memNode      = (*arguments)[0]->getAsTyped();
 
         if (IsBufferOrSharedVariable(memNode))
         {
             return;
         }
@@ -5658,43 +5637,44 @@ void TParseContext::checkAtomicMemoryBui
             {
                 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.",
-              functionName);
+              func->name());
     }
 }
 
 // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
 void TParseContext::checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall)
 {
     ASSERT(functionCall->getOp() == EOpCallBuiltInFunction);
 
-    if (functionCall->getFunction()->isImageFunction())
-    {
-        const ImmutableString &name = functionCall->getFunction()->name();
+    const TFunction *func = functionCall->getFunction();
+
+    if (BuiltInGroup::isImage(func))
+    {
         TIntermSequence *arguments = functionCall->getSequence();
         TIntermTyped *imageNode    = (*arguments)[0]->getAsTyped();
 
         const TMemoryQualifier &memoryQualifier = imageNode->getMemoryQualifier();
 
-        if (strcmp(name.data() + 5u, "Store") == 0)
+        if (BuiltInGroup::isImageStore(func))
         {
             if (memoryQualifier.readonly)
             {
                 error(imageNode->getLine(),
                       "'imageStore' cannot be used with images qualified as 'readonly'",
                       GetImageArgumentToken(imageNode));
             }
         }
-        else if (strcmp(name.data() + 5u, "Load") == 0)
+        else if (BuiltInGroup::isImageLoad(func))
         {
             if (memoryQualifier.writeonly)
             {
                 error(imageNode->getLine(),
                       "'imageLoad' cannot be used with images qualified as 'writeonly'",
                       GetImageArgumentToken(imageNode));
             }
         }
@@ -5711,17 +5691,17 @@ void TParseContext::checkImageMemoryAcce
     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).type;
+        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();
@@ -5795,17 +5775,17 @@ TIntermTyped *TParseContext::addMethod(T
     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);
+        TIntermUnary *node = new TIntermUnary(EOpArrayLength, thisNode, nullptr);
         node->setLine(loc);
         return node->fold(mDiagnostics);
     }
     return CreateZeroNode(TType(EbtInt, EbpUndefined, EvqConst));
 }
 
 TIntermTyped *TParseContext::addNonConstructorFunctionCall(TFunctionLookup *fnCall,
                                                            const TSourceLoc &loc)
@@ -5853,17 +5833,18 @@ TIntermTyped *TParseContext::addNonConst
             TOperator op = fnCandidate->getBuiltInOp();
             if (op != EOpCallBuiltInFunction)
             {
                 // A function call mapped to a built-in operation.
                 if (fnCandidate->getParamCount() == 1)
                 {
                     // Treat it like a built-in unary operator.
                     TIntermNode *unaryParamNode = fnCall->arguments().front();
-                    TIntermTyped *callNode = createUnaryMath(op, unaryParamNode->getAsTyped(), loc);
+                    TIntermTyped *callNode =
+                        createUnaryMath(op, unaryParamNode->getAsTyped(), loc, fnCandidate);
                     ASSERT(callNode != nullptr);
                     return callNode;
                 }
                 TIntermAggregate *callNode =
                     TIntermAggregate::CreateBuiltInFunctionCall(*fnCandidate, &fnCall->arguments());
                 callNode->setLine(loc);
 
                 // Some built-in functions have out parameters too.
@@ -5950,16 +5931,19 @@ TIntermTyped *TParseContext::addTernaryS
     // "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.
--- a/gfx/angle/checkout/src/compiler/translator/ParseContext.h
+++ b/gfx/angle/checkout/src/compiler/translator/ParseContext.h
@@ -414,16 +414,18 @@ class TParseContext : angle::NonCopyable
                             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 checkTextureOffsetConst(TIntermAggregate *functionCall);
     void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall);
     void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition,
                                                        const TIntermAggregate *functionCall);
     void checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall);
 
     // fnCall is only storing the built-in op, and function name or constructor type. arguments
@@ -459,16 +461,18 @@ class TParseContext : angle::NonCopyable
     // 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,
@@ -540,21 +544,20 @@ class TParseContext : angle::NonCopyable
                                 const char *errorMessage,
                                 const ImmutableString &token,
                                 TType *arrayType);
 
     TIntermTyped *addBinaryMathInternal(TOperator op,
                                         TIntermTyped *left,
                                         TIntermTyped *right,
                                         const TSourceLoc &loc);
-    TIntermBinary *createAssign(TOperator op,
-                                TIntermTyped *left,
-                                TIntermTyped *right,
-                                const TSourceLoc &loc);
-    TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *child, 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);
@@ -601,20 +604,16 @@ class TParseContext : angle::NonCopyable
     TLayoutBlockStorage mDefaultUniformBlockStorage;
     TLayoutMatrixPacking mDefaultBufferMatrixPacking;
     TLayoutBlockStorage mDefaultBufferBlockStorage;
     TString mHashErrMsg;
     TDiagnostics *mDiagnostics;
     TDirectiveHandler mDirectiveHandler;
     pp::Preprocessor mPreprocessor;
     void *mScanner;
-    bool mUsesFragData;  // track if we are using both gl_FragData and gl_FragColor
-    bool mUsesFragColor;
-    bool mUsesSecondaryOutputs;  // Track if we are using either gl_SecondaryFragData or
-                                 // gl_Secondary FragColor or both.
     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;
@@ -637,20 +636,16 @@ class TParseContext : angle::NonCopyable
 
     // Track the geometry shader global parameters declared in layout.
     TLayoutPrimitiveType mGeometryShaderInputPrimitiveType;
     TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType;
     int mGeometryShaderInvocations;
     int mGeometryShaderMaxVertices;
     int mMaxGeometryShaderInvocations;
     int mMaxGeometryShaderMaxVertices;
-
-    // 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.
-    const TVariable *mGlInVariableWithArraySize;
 };
 
 int PaParseStrings(size_t count,
                    const char *const string[],
                    const int length[],
                    TParseContext *context);
 
 }  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ParseContext_autogen.h
@@ -0,0 +1,66 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_builtin_symbols.py using data from builtin_variables.json and
+// builtin_function_declarations.txt.
+//
+// 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.
+//
+// ParseContext_autogen.h:
+//   Helpers for built-in related checks.
+
+#ifndef COMPILER_TRANSLATOR_PARSECONTEXT_AUTOGEN_H_
+#define COMPILER_TRANSLATOR_PARSECONTEXT_AUTOGEN_H_
+
+namespace sh
+{
+
+namespace BuiltInGroup
+{
+
+bool isTextureOffsetNoBias(const TFunction *func)
+{
+    int id = func->uniqueId().get();
+    return id >= 662 && id <= 731;
+}
+bool isTextureOffsetBias(const TFunction *func)
+{
+    int id = func->uniqueId().get();
+    return id >= 732 && id <= 751;
+}
+bool isTextureGatherOffset(const TFunction *func)
+{
+    int id = func->uniqueId().get();
+    return id >= 823 && id <= 836;
+}
+bool isTextureGather(const TFunction *func)
+{
+    int id = func->uniqueId().get();
+    return id >= 799 && id <= 836;
+}
+bool isAtomicMemory(const TFunction *func)
+{
+    int id = func->uniqueId().get();
+    return id >= 853 && id <= 870;
+}
+bool isImageLoad(const TFunction *func)
+{
+    int id = func->uniqueId().get();
+    return id >= 895 && id <= 906;
+}
+bool isImageStore(const TFunction *func)
+{
+    int id = func->uniqueId().get();
+    return id >= 907 && id <= 918;
+}
+bool isImage(const TFunction *func)
+{
+    int id = func->uniqueId().get();
+    return id >= 871 && id <= 918;
+}
+
+}  // namespace BuiltInGroup
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_PARSECONTEXT_AUTOGEN_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/PruneNoOps.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// 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.
-
-#include "compiler/translator/PruneNoOps.h"
-
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/Symbol.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:
-    static void apply(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;
-};
-
-void PruneNoOpsTraverser::apply(TIntermBlock *root, TSymbolTable *symbolTable)
-{
-    PruneNoOpsTraverser prune(symbolTable);
-    root->traverse(&prune);
-    prune.updateTree();
-}
-
-PruneNoOpsTraverser::PruneNoOpsTraverser(TSymbolTable *symbolTable)
-    : TIntermTraverser(true, false, false, symbolTable)
-{
-}
-
-bool PruneNoOpsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
-{
-    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.push_back(
-                    NodeReplaceWithMultipleEntry(node, declaratorSymbol, 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, ImmutableString(""), type, SymbolType::Empty);
-                queueReplacementWithParent(node, declaratorSymbol, new TIntermSymbol(variable),
-                                           OriginalNode::IS_DROPPED);
-            }
-        }
-    }
-    return false;
-}
-
-bool PruneNoOpsTraverser::visitBlock(Visit visit, TIntermBlock *node)
-{
-    TIntermSequence *statements = node->getSequence();
-
-    for (TIntermNode *statement : *statements)
-    {
-        if (IsNoOp(statement))
-        {
-            TIntermSequence emptyReplacement;
-            mMultiReplacements.push_back(
-                NodeReplaceWithMultipleEntry(node, statement, emptyReplacement));
-        }
-    }
-
-    return true;
-}
-
-bool PruneNoOpsTraverser::visitLoop(Visit visit, TIntermLoop *loop)
-{
-    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;
-}
-
-}  // namespace
-
-void PruneNoOps(TIntermBlock *root, TSymbolTable *symbolTable)
-{
-    PruneNoOpsTraverser::apply(root, symbolTable);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/PruneNoOps.h
+++ /dev/null
@@ -1,25 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// 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.
-
-#ifndef COMPILER_TRANSLATOR_PRUNENOOPS_H_
-#define COMPILER_TRANSLATOR_PRUNENOOPS_H_
-
-namespace sh
-{
-class TIntermBlock;
-class TSymbolTable;
-
-void PruneNoOps(TIntermBlock *root, TSymbolTable *symbolTable);
-}
-
-#endif  // COMPILER_TRANSLATOR_PRUNENOOPS_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RecordConstantPrecision.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// 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/RecordConstantPrecision.h"
-
-#include "compiler/translator/InfoSink.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class RecordConstantPrecisionTraverser : public TIntermTraverser
-{
-  public:
-    RecordConstantPrecisionTraverser(TSymbolTable *symbolTable);
-
-    void visitConstantUnion(TIntermConstantUnion *node) override;
-
-    void nextIteration();
-
-    bool foundHigherPrecisionConstant() const { return mFoundHigherPrecisionConstant; }
-  protected:
-    bool operandAffectsParentOperationPrecision(TIntermTyped *operand);
-
-    bool mFoundHigherPrecisionConstant;
-};
-
-RecordConstantPrecisionTraverser::RecordConstantPrecisionTraverser(TSymbolTable *symbolTable)
-    : TIntermTraverser(true, false, true, symbolTable), mFoundHigherPrecisionConstant(false)
-{
-}
-
-bool RecordConstantPrecisionTraverser::operandAffectsParentOperationPrecision(TIntermTyped *operand)
-{
-    if (getParentNode()->getAsCaseNode() || getParentNode()->getAsBlock())
-    {
-        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:
-                break;
-        }
-
-        TIntermTyped *otherOperand = parentAsBinary->getRight();
-        if (otherOperand == operand)
-        {
-            otherOperand = parentAsBinary->getLeft();
-        }
-        // If the precision of the other child is at least as high as the precision of the constant,
-        // the precision of the constant has no effect.
-        if (otherOperand->getAsConstantUnion() == nullptr &&
-            otherOperand->getPrecision() >= operand->getPrecision())
-        {
-            return false;
-        }
-    }
-
-    TIntermAggregate *parentAsAggregate = getParentNode()->getAsAggregate();
-    if (parentAsAggregate != nullptr)
-    {
-        if (!parentAsAggregate->gotPrecisionFromChildren())
-        {
-            // This can be either:
-            // * a call to an user-defined function
-            // * a call to a texture function
-            // * some other kind of aggregate
-            // In any of these cases the constant precision has no effect.
-            return false;
-        }
-        if (parentAsAggregate->isConstructor() && parentAsAggregate->getBasicType() == EbtBool)
-        {
-            return false;
-        }
-        // If the precision of operands does affect the result, but the precision of any of the
-        // other children has a precision that's at least as high as the precision of the constant,
-        // the precision of the constant has no effect.
-        TIntermSequence *parameters = parentAsAggregate->getSequence();
-        for (TIntermNode *parameter : *parameters)
-        {
-            const TIntermTyped *typedParameter = parameter->getAsTyped();
-            if (parameter != operand && typedParameter != nullptr &&
-                parameter->getAsConstantUnion() == nullptr &&
-                typedParameter->getPrecision() >= operand->getPrecision())
-            {
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-void RecordConstantPrecisionTraverser::visitConstantUnion(TIntermConstantUnion *node)
-{
-    if (mFoundHigherPrecisionConstant)
-        return;
-
-    // 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);
-    mFoundHigherPrecisionConstant = true;
-}
-
-void RecordConstantPrecisionTraverser::nextIteration()
-{
-    mFoundHigherPrecisionConstant = false;
-}
-
-}  // namespace
-
-void RecordConstantPrecision(TIntermNode *root, TSymbolTable *symbolTable)
-{
-    RecordConstantPrecisionTraverser traverser(symbolTable);
-    // Iterate as necessary, and reset the traverser between iterations.
-    do
-    {
-        traverser.nextIteration();
-        root->traverse(&traverser);
-        if (traverser.foundHigherPrecisionConstant())
-            traverser.updateTree();
-    } while (traverser.foundHigherPrecisionConstant());
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RecordConstantPrecision.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// 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_RECORDCONSTANTPRECISION_H_
-#define COMPILER_TRANSLATOR_RECORDCONSTANTPRECISION_H_
-
-namespace sh
-{
-class TIntermNode;
-class TSymbolTable;
-
-void RecordConstantPrecision(TIntermNode *root, TSymbolTable *symbolTable);
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_RECORDCONSTANTPRECISION_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RegenerateStructNames.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-//
-// Copyright (c) 2002-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/RegenerateStructNames.h"
-
-#include "common/debug.h"
-#include "compiler/translator/ImmutableStringBuilder.h"
-
-namespace sh
-{
-
-namespace
-{
-constexpr const ImmutableString kPrefix("_webgl_struct_");
-}  // anonymous namespace
-
-void RegenerateStructNames::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 RegenerateStructNames::visitBlock(Visit, TIntermBlock *block)
-{
-    ++mScopeDepth;
-    TIntermSequence &sequence = *(block->getSequence());
-    for (TIntermNode *node : sequence)
-    {
-        node->traverse(this);
-    }
-    --mScopeDepth;
-    return false;
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RegenerateStructNames.h
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// Copyright (c) 2002-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_REGENERATESTRUCTNAMES_H_
-#define COMPILER_TRANSLATOR_REGENERATESTRUCTNAMES_H_
-
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/SymbolTable.h"
-
-#include <set>
-
-namespace sh
-{
-
-class RegenerateStructNames : public TIntermTraverser
-{
-  public:
-    RegenerateStructNames(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's declared globally, push its ID in this set.
-    std::set<int> mDeclaredGlobalStructs;
-};
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_REGENERATESTRUCTNAMES_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RemoveArrayLengthMethod.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-//
-// Copyright (c) 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/RemoveArrayLengthMethod.h"
-
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/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:
-    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;
-        if (!node->getOperand()->hasSideEffects())
-        {
-            queueReplacement(node->fold(nullptr), OriginalNode::IS_DROPPED);
-            return false;
-        }
-        insertStatementInParentBlock(node->getOperand()->deepCopy());
-        TConstantUnion *constArray = new TConstantUnion[1];
-        constArray->setIConst(node->getOperand()->getOutermostArraySize());
-        queueReplacement(new TIntermConstantUnion(constArray, node->getType()),
-                         OriginalNode::IS_DROPPED);
-        return false;
-    }
-    return true;
-}
-
-}  // anonymous namespace
-
-void RemoveArrayLengthMethod(TIntermBlock *root)
-{
-    RemoveArrayLengthTraverser traverser;
-    do
-    {
-        traverser.nextIteration();
-        root->traverse(&traverser);
-        if (traverser.foundArrayLength())
-            traverser.updateTree();
-    } while (traverser.foundArrayLength());
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RemoveArrayLengthMethod.h
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Copyright (c) 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.
-
-namespace sh
-{
-
-class TIntermBlock;
-
-void RemoveArrayLengthMethod(TIntermBlock *root);
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RemoveDynamicIndexing.cpp
+++ /dev/null
@@ -1,548 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// RemoveDynamicIndexing is an AST traverser to remove dynamic indexing of vectors and matrices,
-// replacing them with calls to functions that choose which component to return or write.
-//
-
-#include "compiler/translator/RemoveDynamicIndexing.h"
-
-#include "compiler/translator/Diagnostics.h"
-#include "compiler/translator/InfoSink.h"
-#include "compiler/translator/IntermNodePatternMatcher.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/StaticType.h"
-#include "compiler/translator/SymbolTable.h"
-
-namespace sh
-{
-
-namespace
-{
-
-const TType *kIndexType = StaticType::Get<EbtInt, EbpHigh, EvqIn, 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" << type.getCols() << "x" << 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 << type.getNominalSize();
-    }
-    return nameSink.str();
-}
-
-TIntermSymbol *CreateParameterSymbol(const TConstParameter &parameter, TSymbolTable *symbolTable)
-{
-    TVariable *variable =
-        new TVariable(symbolTable, parameter.name, parameter.type, SymbolType::AngleInternal);
-    return new TIntermSymbol(variable);
-}
-
-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 = new TIntermSequence();
-    arguments->push_back(node);
-    return TIntermAggregate::CreateConstructor(TType(EbtInt), arguments);
-}
-
-TType *GetFieldType(const TType &indexedType)
-{
-    if (indexedType.isMatrix())
-    {
-        TType *fieldType = new TType(indexedType.getBasicType(), indexedType.getPrecision());
-        fieldType->setPrimarySize(static_cast<unsigned char>(indexedType.getRows()));
-        return fieldType;
-    }
-    else
-    {
-        return new TType(indexedType.getBasicType(), indexedType.getPrecision());
-    }
-}
-
-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(EvqInOut);
-    if (!write)
-        baseType->setQualifier(EvqIn);
-    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());
-
-    int numCases    = 0;
-    if (type.isMatrix())
-    {
-        numCases = type.getCols();
-    }
-    else
-    {
-        numCases = type.getNominalSize();
-    }
-
-    std::string functionName                = GetIndexFunctionName(type, write);
-    TIntermFunctionPrototype *prototypeNode = CreateInternalFunctionPrototypeNode(func);
-
-    TIntermSymbol *baseParam = CreateParameterSymbol(func.getParam(0), symbolTable);
-    prototypeNode->getSequence()->push_back(baseParam);
-    TIntermSymbol *indexParam = CreateParameterSymbol(func.getParam(1), symbolTable);
-    prototypeNode->getSequence()->push_back(indexParam);
-    TIntermSymbol *valueParam = nullptr;
-    if (write)
-    {
-        valueParam = CreateParameterSymbol(func.getParam(2), symbolTable);
-        prototypeNode->getSequence()->push_back(valueParam);
-    }
-
-    TIntermBlock *statementList = new TIntermBlock();
-    for (int 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(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;
-
-    PerformanceDiagnostics *mPerfDiagnostics;
-};
-
-RemoveDynamicIndexingTraverser::RemoveDynamicIndexingTraverser(
-    TSymbolTable *symbolTable,
-    PerformanceDiagnostics *perfDiagnostics)
-    : TLValueTrackingTraverser(true, false, false, symbolTable),
-      mUsedTreeInsertion(false),
-      mRemoveIndexSideEffectsInSubtree(false),
-      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 = new TIntermSequence();
-    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 = new TIntermSequence();
-    // 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 (IntermNodePatternMatcher::IsDynamicIndexingOfVectorOrMatrix(node))
-        {
-            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(
-                    TConstParameter(kBaseName, GetBaseType(type, false)));
-                indexingFunction->addParameter(TConstParameter(kIndexName, kIndexType));
-                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 &&
-                    IntermNodePatternMatcher::IsDynamicIndexingOfVectorOrMatrix(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>(), false);
-                    indexedWriteFunction->addParameter(
-                        TConstParameter(kBaseName, GetBaseType(type, true)));
-                    indexedWriteFunction->addParameter(TConstParameter(kIndexName, kIndexType));
-                    TType *valueType = GetFieldType(type);
-                    valueType->setQualifier(EvqIn);
-                    indexedWriteFunction->addParameter(
-                        TConstParameter(kValueName, static_cast<const TType *>(valueType)));
-                    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;
-}
-
-}  // namespace
-
-void RemoveDynamicIndexing(TIntermNode *root,
-                           TSymbolTable *symbolTable,
-                           PerformanceDiagnostics *perfDiagnostics)
-{
-    RemoveDynamicIndexingTraverser traverser(symbolTable, perfDiagnostics);
-    do
-    {
-        traverser.nextIteration();
-        root->traverse(&traverser);
-        traverser.updateTree();
-    } 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);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RemoveDynamicIndexing.h
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// RemoveDynamicIndexing is an AST traverser to remove dynamic indexing of vectors and matrices,
-// replacing them with calls to functions that choose which component to return or write.
-//
-
-#ifndef COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_
-#define COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_
-
-namespace sh
-{
-
-class TIntermNode;
-class TSymbolTable;
-class PerformanceDiagnostics;
-
-void RemoveDynamicIndexing(TIntermNode *root,
-                           TSymbolTable *symbolTable,
-                           PerformanceDiagnostics *perfDiagnostics);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RemoveEmptySwitchStatements.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-//
-// Copyright (c) 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.
-//
-// RemoveEmptySwitchStatements.cpp: Remove switch statements that have an empty statement list.
-
-#include "compiler/translator/RemoveEmptySwitchStatements.h"
-
-#include "compiler/translator/IntermTraverse.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class RemoveEmptySwitchStatementsTraverser : public TIntermTraverser
-{
-  public:
-    RemoveEmptySwitchStatementsTraverser() : TIntermTraverser(true, false, false) {}
-
-    bool visitSwitch(Visit visit, TIntermSwitch *node);
-};
-
-bool RemoveEmptySwitchStatementsTraverser::visitSwitch(Visit visit, TIntermSwitch *node)
-{
-    if (node->getStatementList()->getSequence()->empty())
-    {
-        // Just output the init statement.
-        if (node->getInit()->hasSideEffects())
-        {
-            queueReplacement(node->getInit(), OriginalNode::IS_DROPPED);
-        }
-        else
-        {
-            TIntermSequence emptyReplacement;
-            ASSERT(getParentNode()->getAsBlock());
-            mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(),
-                                                                      node, emptyReplacement));
-        }
-        return false;  // Nothing inside the child nodes to traverse.
-    }
-    return true;
-}
-
-}  // anonymous namespace
-
-void RemoveEmptySwitchStatements(TIntermBlock *root)
-{
-    RemoveEmptySwitchStatementsTraverser traverser;
-    root->traverse(&traverser);
-    traverser.updateTree();
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RemoveEmptySwitchStatements.h
+++ /dev/null
@@ -1,18 +0,0 @@
-//
-// Copyright (c) 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.
-//
-// RemoveEmptySwitchStatements.h: Remove switch statements that have an empty statement list.
-
-#ifndef COMPILER_TRANSLATOR_REMOVEEMPTYSWITCHSTATEMENTS_H_
-#define COMPILER_TRANSLATOR_REMOVEEMPTYSWITCHSTATEMENTS_H_
-
-namespace sh
-{
-class TIntermBlock;
-
-void RemoveEmptySwitchStatements(TIntermBlock *root);
-}
-
-#endif  // COMPILER_TRANSLATOR_REMOVEEMPTYSWITCHSTATEMENTS_H_
\ No newline at end of file
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RemoveInvariantDeclaration.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-//
-// Copyright (c) 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/RemoveInvariantDeclaration.h"
-
-#include "compiler/translator/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 visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node) override
-    {
-        TIntermSequence emptyReplacement;
-        mMultiReplacements.push_back(
-            NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(), node, emptyReplacement));
-        return false;
-    }
-};
-
-}  // anonymous namespace
-
-void RemoveInvariantDeclaration(TIntermNode *root)
-{
-    RemoveInvariantDeclarationTraverser traverser;
-    root->traverse(&traverser);
-    traverser.updateTree();
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RemoveInvariantDeclaration.h
+++ /dev/null
@@ -1,18 +0,0 @@
-//
-// Copyright (c) 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_REMOVEINVARIANTDECLARATION_H_
-#define COMPILER_TRANSLATOR_REMOVEINVARIANTDECLARATION_H_
-
-class TIntermNode;
-namespace sh
-{
-
-void RemoveInvariantDeclaration(TIntermNode *root);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_REMOVEINVARIANTDECLARATION_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-//
-// Copyright (c) 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.
-//
-// RemoveNoOpCasesFromEndOfSwitchStatements.cpp: Clean up cases from the end of a switch statement
-// that only contain no-ops.
-
-#include "compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.h"
-
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/SymbolTable.h"
-
-namespace sh
-{
-
-namespace
-{
-
-bool AreEmptyBlocks(TIntermSequence *statements, size_t i);
-
-bool IsEmptyBlock(TIntermNode *node)
-{
-    TIntermBlock *asBlock = node->getAsBlock();
-    if (asBlock)
-    {
-        if (asBlock->getSequence()->empty())
-        {
-            return true;
-        }
-        return AreEmptyBlocks(asBlock->getSequence(), 0u);
-    }
-    // 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" starting from index i consist only of empty blocks
-// and no-op statements. Returns true also if there are no statements.
-bool AreEmptyBlocks(TIntermSequence *statements, size_t i)
-{
-    for (; i < statements->size(); ++i)
-    {
-        if (!IsEmptyBlock(statements->at(i)))
-        {
-            return false;
-        }
-    }
-    return true;
-}
-
-void RemoveNoOpCasesFromEndOfStatementList(TIntermBlock *statementList, TSymbolTable *symbolTable)
-{
-    TIntermSequence *statements = statementList->getSequence();
-
-    bool foundDeadCase = false;
-    do
-    {
-        if (statements->empty())
-        {
-            return;
-        }
-
-        // Find the last case label.
-        size_t i = statements->size();
-        while (i > 0u && !(*statements)[i - 1]->getAsCaseNode())
-        {
-            --i;
-        }
-        // Now i is the index of the first statement following the last label inside the switch
-        // statement.
-        ASSERT(i > 0u);
-
-        foundDeadCase = AreEmptyBlocks(statements, i);
-        if (foundDeadCase)
-        {
-            statements->erase(statements->begin() + (i - 1u), statements->end());
-        }
-    } while (foundDeadCase);
-}
-
-class RemoveNoOpCasesFromEndOfSwitchTraverser : public TIntermTraverser
-{
-  public:
-    RemoveNoOpCasesFromEndOfSwitchTraverser(TSymbolTable *symbolTable)
-        : TIntermTraverser(true, false, false, symbolTable)
-    {
-    }
-
-    bool visitSwitch(Visit visit, TIntermSwitch *node) override;
-};
-
-bool RemoveNoOpCasesFromEndOfSwitchTraverser::visitSwitch(Visit visit, TIntermSwitch *node)
-{
-    // Here we may mutate the statement list, but it's safe since traversal has not yet reached
-    // there.
-    RemoveNoOpCasesFromEndOfStatementList(node->getStatementList(), mSymbolTable);
-    // Handle also nested switch statements.
-    return true;
-}
-
-}  // anonymous namespace
-
-void RemoveNoOpCasesFromEndOfSwitchStatements(TIntermBlock *root, TSymbolTable *symbolTable)
-{
-    RemoveNoOpCasesFromEndOfSwitchTraverser traverser(symbolTable);
-    root->traverse(&traverser);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.h
+++ /dev/null
@@ -1,21 +0,0 @@
-//
-// Copyright (c) 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.
-//
-// RemoveNoOpCasesFromEndOfSwitchStatements.h: Clean up cases from the end of a switch statement
-// that only contain no-ops.
-
-#ifndef COMPILER_TRANSLATOR_REMOVENOOPCASESFROMENDOFSWITCHSTATEMENTS_H_
-#define COMPILER_TRANSLATOR_REMOVENOOPCASESFROMENDOFSWITCHSTATEMENTS_H_
-
-namespace sh
-{
-class TIntermBlock;
-class TSymbolTable;
-
-void RemoveNoOpCasesFromEndOfSwitchStatements(TIntermBlock *root, TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_REMOVENOOPCASESFROMENDOFSWITCHSTATEMENTS_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RemovePow.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// RemovePow is an AST traverser to convert pow(x, y) built-in calls where y is a
-// constant to exp2(y * log2(x)). This works around an issue in NVIDIA 311 series
-// OpenGL drivers.
-//
-
-#include "compiler/translator/RemovePow.h"
-
-#include "compiler/translator/InfoSink.h"
-#include "compiler/translator/IntermTraverse.h"
-
-namespace sh
-{
-
-namespace
-{
-
-bool IsProblematicPow(TIntermTyped *node)
-{
-    TIntermAggregate *agg = node->getAsAggregate();
-    if (agg != nullptr && agg->getOp() == EOpPow)
-    {
-        ASSERT(agg->getSequence()->size() == 2);
-        return agg->getSequence()->at(1)->getAsConstantUnion() != nullptr;
-    }
-    return false;
-}
-
-// Traverser that converts all pow operations simultaneously.
-class RemovePowTraverser : public TIntermTraverser
-{
-  public:
-    RemovePowTraverser();
-
-    bool visitAggregate(Visit visit, TIntermAggregate *node) override;
-
-    void nextIteration() { mNeedAnotherIteration = false; }
-    bool needAnotherIteration() const { return mNeedAnotherIteration; }
-
-  protected:
-    bool mNeedAnotherIteration;
-};
-
-RemovePowTraverser::RemovePowTraverser()
-    : TIntermTraverser(true, false, false), mNeedAnotherIteration(false)
-{
-}
-
-bool RemovePowTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
-{
-    if (IsProblematicPow(node))
-    {
-        TIntermTyped *x = node->getSequence()->at(0)->getAsTyped();
-        TIntermTyped *y = node->getSequence()->at(1)->getAsTyped();
-
-        TIntermUnary *log = new TIntermUnary(EOpLog2, x);
-        log->setLine(node->getLine());
-
-        TOperator op       = TIntermBinary::GetMulOpBasedOnOperands(y->getType(), log->getType());
-        TIntermBinary *mul = new TIntermBinary(op, y, log);
-        mul->setLine(node->getLine());
-
-        TIntermUnary *exp = new TIntermUnary(EOpExp2, mul);
-        exp->setLine(node->getLine());
-
-        queueReplacement(exp, OriginalNode::IS_DROPPED);
-
-        // If the x parameter also needs to be replaced, we need to do that in another traversal,
-        // since it's parent node will change in a way that's not handled correctly by updateTree().
-        if (IsProblematicPow(x))
-        {
-            mNeedAnotherIteration = true;
-            return false;
-        }
-    }
-    return true;
-}
-
-}  // namespace
-
-void RemovePow(TIntermNode *root)
-{
-    RemovePowTraverser traverser;
-    // Iterate as necessary, and reset the traverser between iterations.
-    do
-    {
-        traverser.nextIteration();
-        root->traverse(&traverser);
-        traverser.updateTree();
-    } while (traverser.needAnotherIteration());
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RemovePow.h
+++ /dev/null
@@ -1,21 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// RemovePow is an AST traverser to convert pow(x, y) built-in calls where y is a
-// constant to exp2(y * log2(x)). This works around an issue in NVIDIA 311 series
-// OpenGL drivers.
-//
-
-#ifndef COMPILER_TRANSLATOR_REMOVEPOW_H_
-#define COMPILER_TRANSLATOR_REMOVEPOW_H_
-
-namespace sh
-{
-class TIntermNode;
-
-void RemovePow(TIntermNode *root);
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_REMOVEPOW_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RemoveSwitchFallThrough.cpp
+++ /dev/null
@@ -1,270 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// 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/RemoveSwitchFallThrough.h"
-
-#include "compiler/translator/Diagnostics.h"
-#include "compiler/translator/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
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RemoveSwitchFallThrough.h
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// 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_REMOVESWITCHFALLTHROUGH_H_
-#define COMPILER_TRANSLATOR_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_REMOVESWITCHFALLTHROUGH_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RemoveUnreferencedVariables.cpp
+++ /dev/null
@@ -1,370 +0,0 @@
-//
-// Copyright (c) 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/RemoveUnreferencedVariables.h"
-
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/SymbolTable.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class CollectVariableRefCountsTraverser : public TIntermTraverser
-{
-  public:
-    CollectVariableRefCountsTraverser();
-
-    using RefCountMap = std::unordered_map<int, unsigned int>;
-    RefCountMap &getSymbolIdRefCounts() { return mSymbolIdRefCounts; }
-    RefCountMap &getStructIdRefCounts() { return mStructIdRefCounts; }
-
-    void visitSymbol(TIntermSymbol *node) override;
-    bool visitAggregate(Visit visit, TIntermAggregate *node) override;
-    bool visitFunctionPrototype(Visit visit, 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;
-}
-
-bool CollectVariableRefCountsTraverser::visitFunctionPrototype(Visit visit,
-                                                               TIntermFunctionPrototype *node)
-{
-    incrementStructTypeRefCount(node->getType());
-    return true;
-}
-
-// 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, ImmutableString(""), new TType(declarator->getType()),
-                              SymbolType::Empty);
-            queueReplacementWithParent(node, declarator, new TIntermSymbol(emptyVariable),
-                                       OriginalNode::IS_DROPPED);
-            return;
-        }
-    }
-
-    if (getParentNode()->getAsBlock())
-    {
-        TIntermSequence emptyReplacement;
-        mMultiReplacements.push_back(
-            NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(), node, 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
-
-void RemoveUnreferencedVariables(TIntermBlock *root, TSymbolTable *symbolTable)
-{
-    CollectVariableRefCountsTraverser collector;
-    root->traverse(&collector);
-    RemoveUnreferencedVariablesTraverser traverser(&collector.getSymbolIdRefCounts(),
-                                                   &collector.getStructIdRefCounts(), symbolTable);
-    root->traverse(&traverser);
-    traverser.updateTree();
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RemoveUnreferencedVariables.h
+++ /dev/null
@@ -1,24 +0,0 @@
-//
-// Copyright (c) 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_REMOVEUNREFERENCEDVARIABLES_H_
-#define COMPILER_TRANSLATOR_REMOVEUNREFERENCEDVARIABLES_H_
-
-namespace sh
-{
-
-class TIntermBlock;
-class TSymbolTable;
-
-void RemoveUnreferencedVariables(TIntermBlock *root, TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_REMOVEUNREFERENCEDVARIABLES_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ReplaceVariable.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// Copyright (c) 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/ReplaceVariable.h"
-
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/IntermTraverse.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class ReplaceVariableTraverser : public TIntermTraverser
-{
-  public:
-    ReplaceVariableTraverser(const TVariable *toBeReplaced, const TVariable *replacement)
-        : TIntermTraverser(true, false, false),
-          mToBeReplaced(toBeReplaced),
-          mReplacement(replacement)
-    {
-    }
-
-    void visitSymbol(TIntermSymbol *node) override
-    {
-        if (&node->variable() == mToBeReplaced)
-        {
-            queueReplacement(new TIntermSymbol(mReplacement), OriginalNode::IS_DROPPED);
-        }
-    }
-
-  private:
-    const TVariable *const mToBeReplaced;
-    const TVariable *const mReplacement;
-};
-
-}  // anonymous namespace
-
-// Replaces every occurrence of a variable with another variable.
-void ReplaceVariable(TIntermBlock *root,
-                     const TVariable *toBeReplaced,
-                     const TVariable *replacement)
-{
-    ReplaceVariableTraverser traverser(toBeReplaced, replacement);
-    root->traverse(&traverser);
-    traverser.updateTree();
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ReplaceVariable.h
+++ /dev/null
@@ -1,24 +0,0 @@
-//
-// Copyright (c) 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_REPLACEVARIABLE_H_
-#define COMPILER_TRANSLATOR_REPLACEVARIABLE_H_
-
-namespace sh
-{
-
-class TIntermBlock;
-class TVariable;
-
-void ReplaceVariable(TIntermBlock *root,
-                     const TVariable *toBeReplaced,
-                     const TVariable *replacement);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_REPLACEVARIABLE_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RewriteDoWhile.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-//
-// Copyright (c) 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/RewriteDoWhile.h"
-
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/StaticType.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());
-
-                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
-
-void RewriteDoWhile(TIntermNode *root, TSymbolTable *symbolTable)
-{
-    DoWhileRewriter rewriter(symbolTable);
-
-    root->traverse(&rewriter);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RewriteDoWhile.h
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright (c) 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_REWRITEDOWHILE_H_
-#define COMPILER_TRANSLATOR_REWRITEDOWHILE_H_
-
-namespace sh
-{
-
-class TIntermNode;
-class TSymbolTable;
-
-void RewriteDoWhile(TIntermNode *root, TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_REWRITEDOWHILE_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RewriteElseBlocks.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-//
-// Copyright (c) 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/RewriteElseBlocks.h"
-
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/NodeSearch.h"
-#include "compiler/translator/SymbolTable.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 dummy
-        // 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);
-        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
-
-void RewriteElseBlocks(TIntermNode *node, TSymbolTable *symbolTable)
-{
-    ElseBlockRewriter rewriter(symbolTable);
-    node->traverse(&rewriter);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RewriteElseBlocks.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//
-// Copyright (c) 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_REWRITEELSEBLOCKS_H_
-#define COMPILER_TRANSLATOR_REWRITEELSEBLOCKS_H_
-
-namespace sh
-{
-
-class TIntermNode;
-class TSymbolTable;
-
-void RewriteElseBlocks(TIntermNode *node, TSymbolTable *symbolTable);
-}
-
-#endif  // COMPILER_TRANSLATOR_REWRITEELSEBLOCKS_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RewriteTexelFetchOffset.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-//
-// Copyright (c) 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/RewriteTexelFetchOffset.h"
-
-#include "common/angleutils.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/SymbolTable.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class Traverser : public TIntermTraverser
-{
-  public:
-    static void Apply(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
-void Traverser::Apply(TIntermNode *root, const TSymbolTable &symbolTable, int shaderVersion)
-{
-    Traverser traverser(symbolTable, shaderVersion);
-    do
-    {
-        traverser.nextIteration();
-        root->traverse(&traverser);
-        if (traverser.mFound)
-        {
-            traverser.updateTree();
-        }
-    } while (traverser.mFound);
-}
-
-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 (node->getOp() != EOpCallBuiltInFunction)
-    {
-        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 = new TIntermSequence();
-
-    // 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 = new TIntermSequence();
-        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
-
-void RewriteTexelFetchOffset(TIntermNode *root, const TSymbolTable &symbolTable, int shaderVersion)
-{
-    // texelFetchOffset is only valid in GLSL 3.0 and later.
-    if (shaderVersion < 300)
-        return;
-
-    Traverser::Apply(root, symbolTable, shaderVersion);
-}
-
-}  // namespace sh
\ No newline at end of file
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RewriteTexelFetchOffset.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// Copyright (c) 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_REWRITE_TEXELFETCHOFFSET_H_
-#define COMPILER_TRANSLATOR_REWRITE_TEXELFETCHOFFSET_H_
-
-class TIntermNode;
-class TSymbolTable;
-
-namespace sh
-{
-
-void RewriteTexelFetchOffset(TIntermNode *root, const TSymbolTable &symbolTable, int shaderVersion);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_REWRITE_TEXELFETCHOFFSET_H_
\ No newline at end of file
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RewriteUnaryMinusOperatorFloat.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-//
-// Copyright (c) 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/RewriteUnaryMinusOperatorFloat.h"
-
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class Traverser : public TIntermTraverser
-{
-  public:
-    static void Apply(TIntermNode *root);
-
-  private:
-    Traverser();
-    bool visitUnary(Visit visit, TIntermUnary *node) override;
-    void nextIteration();
-
-    bool mFound = false;
-};
-
-// static
-void Traverser::Apply(TIntermNode *root)
-{
-    Traverser traverser;
-    do
-    {
-        traverser.nextIteration();
-        root->traverse(&traverser);
-        if (traverser.mFound)
-        {
-            traverser.updateTree();
-        }
-    } while (traverser.mFound);
-}
-
-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
-
-void RewriteUnaryMinusOperatorFloat(TIntermNode *root)
-{
-    Traverser::Apply(root);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RewriteUnaryMinusOperatorFloat.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 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_REWRITEUNARYMINUSOPERATORFLOAT_H_
-#define COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORFLOAT_H_
-
-class TIntermNode;
-namespace sh
-{
-
-void RewriteUnaryMinusOperatorFloat(TIntermNode *root);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORFLOAT_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-//
-// Copyright (c) 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/RewriteUnaryMinusOperatorInt.h"
-
-#include "compiler/translator/IntermTraverse.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class Traverser : public TIntermTraverser
-{
-  public:
-    static void Apply(TIntermNode *root);
-
-  private:
-    Traverser();
-    bool visitUnary(Visit visit, TIntermUnary *node) override;
-    void nextIteration();
-
-    bool mFound = false;
-};
-
-// static
-void Traverser::Apply(TIntermNode *root)
-{
-    Traverser traverser;
-    do
-    {
-        traverser.nextIteration();
-        root->traverse(&traverser);
-        if (traverser.mFound)
-        {
-            traverser.updateTree();
-        }
-    } while (traverser.mFound);
-}
-
-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);
-    bitwiseNot->setLine(opr->getLine());
-
-    // Constant 1 (or 1u)
-    TConstantUnion *one = new TConstantUnion();
-    if (opr->getType().getBasicType() == EbtInt)
-    {
-        one->setIConst(1);
-    }
-    else
-    {
-        one->setUConst(1u);
-    }
-    TIntermConstantUnion *oneNode =
-        new TIntermConstantUnion(one, TType(opr->getBasicType(), opr->getPrecision(), EvqConst));
-    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
-
-void RewriteUnaryMinusOperatorInt(TIntermNode *root)
-{
-    Traverser::Apply(root);
-}
-
-}  // namespace sh
\ No newline at end of file
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RewriteUnaryMinusOperatorInt.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 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_REWRITEUNARYMINUSOPERATORINT_H_
-#define COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORINT_H_
-
-class TIntermNode;
-namespace sh
-{
-
-void RewriteUnaryMinusOperatorInt(TIntermNode *root);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORINT_H_
\ No newline at end of file
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RunAtTheEndOfShader.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-//
-// Copyright (c) 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.
-//
-
-#include "compiler/translator/RunAtTheEndOfShader.h"
-
-#include "compiler/translator/FindMain.h"
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/StaticType.h"
-#include "compiler/translator/SymbolTable.h"
-
-namespace sh
-{
-
-namespace
-{
-
-constexpr const ImmutableString kMainString("main");
-
-class ContainsReturnTraverser : public TIntermTraverser
-{
-  public:
-    ContainsReturnTraverser() : TIntermTraverser(true, false, false), mContainsReturn(false) {}
-
-    bool visitBranch(Visit visit, TIntermBranch *node) override
-    {
-        if (node->getFlowOp() == EOpReturn)
-        {
-            mContainsReturn = true;
-        }
-        return false;
-    }
-
-    bool containsReturn() { return mContainsReturn; }
-
-  private:
-    bool mContainsReturn;
-};
-
-bool ContainsReturn(TIntermNode *node)
-{
-    ContainsReturnTraverser traverser;
-    node->traverse(&traverser);
-    return traverser.containsReturn();
-}
-
-void WrapMainAndAppend(TIntermBlock *root,
-                       TIntermFunctionDefinition *main,
-                       TIntermNode *codeToRun,
-                       TSymbolTable *symbolTable)
-{
-    // Replace main() with main0() with the same body.
-    TFunction *oldMain = new TFunction(symbolTable, ImmutableString(""), SymbolType::AngleInternal,
-                                       StaticType::GetBasic<EbtVoid>(), 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>(), false);
-    TIntermFunctionPrototype *newMainProto = new TIntermFunctionPrototype(newMain);
-
-    // {
-    //     main0();
-    //     codeToRun
-    // }
-    TIntermBlock *newMainBody     = new TIntermBlock();
-    TIntermAggregate *oldMainCall =
-        TIntermAggregate::CreateFunctionCall(*oldMain, new TIntermSequence());
-    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
-
-void RunAtTheEndOfShader(TIntermBlock *root, TIntermNode *codeToRun, TSymbolTable *symbolTable)
-{
-    TIntermFunctionDefinition *main = FindMain(root);
-    if (!ContainsReturn(main))
-    {
-        main->getBody()->appendStatement(codeToRun);
-        return;
-    }
-
-    WrapMainAndAppend(root, main, codeToRun, symbolTable);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/RunAtTheEndOfShader.h
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright (c) 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_RUNATTHEENDOFSHADER_H_
-#define COMPILER_TRANSLATOR_RUNATTHEENDOFSHADER_H_
-
-namespace sh
-{
-
-class TIntermBlock;
-class TIntermNode;
-class TSymbolTable;
-
-void RunAtTheEndOfShader(TIntermBlock *root, TIntermNode *codeToRun, TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_RUNATTHEENDOFSHADER_H_
\ No newline at end of file
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
+++ /dev/null
@@ -1,227 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// 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 "common/debug.h"
-#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h"
-
-#include <algorithm>
-
-#include "angle_gl.h"
-#include "common/angleutils.h"
-#include "compiler/translator/IntermNodePatternMatcher.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-
-namespace sh
-{
-
-namespace
-{
-
-TIntermBinary *ConstructVectorIndexBinaryNode(TIntermSymbol *symbolNode, int index)
-{
-    return new TIntermBinary(EOpIndexDirect, symbolNode, CreateIndexNode(index));
-}
-
-TIntermBinary *ConstructMatrixIndexBinaryNode(TIntermSymbol *symbolNode, int colIndex, int rowIndex)
-{
-    TIntermBinary *colVectorNode = ConstructVectorIndexBinaryNode(symbolNode, colIndex);
-
-    return new TIntermBinary(EOpIndexDirect, colVectorNode, CreateIndexNode(rowIndex));
-}
-
-class ScalarizeArgsTraverser : public TIntermTraverser
-{
-  public:
-    ScalarizeArgsTraverser(sh::GLenum shaderType,
-                           bool fragmentPrecisionHigh,
-                           TSymbolTable *symbolTable)
-        : TIntermTraverser(true, false, false, symbolTable),
-          mShaderType(shaderType),
-          mFragmentPrecisionHigh(fragmentPrecisionHigh),
-          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.
-    TVariable *createTempVariable(TIntermTyped *original);
-
-    std::vector<TIntermSequence> mBlockStack;
-
-    sh::GLenum mShaderType;
-    bool mFragmentPrecisionHigh;
-
-    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);
-        TVariable *argVariable = createTempVariable(originalArg);
-        if (originalArg->isScalar())
-        {
-            sequence->push_back(CreateTempSymbolNode(argVariable));
-            size--;
-        }
-        else if (originalArg->isVector())
-        {
-            if (scalarizeVector)
-            {
-                int repeat = std::min(size, originalArg->getNominalSize());
-                size -= repeat;
-                for (int index = 0; index < repeat; ++index)
-                {
-                    TIntermSymbol *symbolNode = CreateTempSymbolNode(argVariable);
-                    TIntermBinary *newNode    = ConstructVectorIndexBinaryNode(symbolNode, index);
-                    sequence->push_back(newNode);
-                }
-            }
-            else
-            {
-                TIntermSymbol *symbolNode = CreateTempSymbolNode(argVariable);
-                sequence->push_back(symbolNode);
-                size -= originalArg->getNominalSize();
-            }
-        }
-        else
-        {
-            ASSERT(originalArg->isMatrix());
-            if (scalarizeMatrix)
-            {
-                int colIndex = 0, rowIndex = 0;
-                int repeat = std::min(size, originalArg->getCols() * originalArg->getRows());
-                size -= repeat;
-                while (repeat > 0)
-                {
-                    TIntermSymbol *symbolNode = CreateTempSymbolNode(argVariable);
-                    TIntermBinary *newNode =
-                        ConstructMatrixIndexBinaryNode(symbolNode, colIndex, rowIndex);
-                    sequence->push_back(newNode);
-                    rowIndex++;
-                    if (rowIndex >= originalArg->getRows())
-                    {
-                        rowIndex = 0;
-                        colIndex++;
-                    }
-                    repeat--;
-                }
-            }
-            else
-            {
-                TIntermSymbol *symbolNode = CreateTempSymbolNode(argVariable);
-                sequence->push_back(symbolNode);
-                size -= originalArg->getCols() * originalArg->getRows();
-            }
-        }
-    }
-}
-
-TVariable *ScalarizeArgsTraverser::createTempVariable(TIntermTyped *original)
-{
-    ASSERT(original);
-
-    TType *type = new TType(original->getType());
-    type->setQualifier(EvqTemporary);
-    if (mShaderType == GL_FRAGMENT_SHADER && type->getBasicType() == EbtFloat &&
-        type->getPrecision() == EbpUndefined)
-    {
-        // We use the highest available precision for the temporary variable
-        // to avoid computing the actual precision using the rules defined
-        // in GLSL ES 1.0 Section 4.5.2.
-        type->setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
-    }
-
-    TVariable *variable = CreateTempVariable(mSymbolTable, type);
-
-    ASSERT(mBlockStack.size() > 0);
-    TIntermSequence &sequence = mBlockStack.back();
-    TIntermDeclaration *declaration = CreateTempInitDeclarationNode(variable, original);
-    sequence.push_back(declaration);
-
-    return variable;
-}
-
-}  // namespace anonymous
-
-void ScalarizeVecAndMatConstructorArgs(TIntermBlock *root,
-                                       sh::GLenum shaderType,
-                                       bool fragmentPrecisionHigh,
-                                       TSymbolTable *symbolTable)
-{
-    ScalarizeArgsTraverser scalarizer(shaderType, fragmentPrecisionHigh, symbolTable);
-    root->traverse(&scalarizer);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// 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_SCALARIZEVECANDMATCONSTRUCTORARGS_H_
-#define COMPILER_TRANSLATOR_SCALARIZEVECANDMATCONSTRUCTORARGS_H_
-
-#include "GLSLANG/ShaderLang.h"
-
-namespace sh
-{
-class TIntermBlock;
-class TSymbolTable;
-
-void ScalarizeVecAndMatConstructorArgs(TIntermBlock *root,
-                                       sh::GLenum shaderType,
-                                       bool fragmentPrecisionHigh,
-                                       TSymbolTable *symbolTable);
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_SCALARIZEVECANDMATCONSTRUCTORARGS_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/SeparateArrayConstructorStatements.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-//
-// Copyright (c) 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/SeparateArrayConstructorStatements.h"
-
-#include "compiler/translator/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.push_back(
-        NodeReplaceWithMultipleEntry(parentAsBlock, node, constructorArgs));
-
-    return false;
-}
-
-}  // namespace
-
-void SeparateArrayConstructorStatements(TIntermBlock *root)
-{
-    SeparateArrayConstructorStatementsTraverser traverser;
-    root->traverse(&traverser);
-    traverser.updateTree();
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/SeparateArrayConstructorStatements.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//
-// Copyright (c) 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_SEPARATEARRAYCONSTRUCTORSTATEMENTS_H_
-#define COMPILER_TRANSLATOR_SEPARATEARRAYCONSTRUCTORSTATEMENTS_H_
-
-namespace sh
-{
-class TIntermBlock;
-
-void SeparateArrayConstructorStatements(TIntermBlock *root);
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_SEPARATEARRAYCONSTRUCTORSTATEMENTS_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/SeparateArrayInitialization.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// 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/SeparateArrayInitialization.h"
-
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/OutputHLSL.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class SeparateArrayInitTraverser : private TIntermTraverser
-{
-  public:
-    static void apply(TIntermNode *root);
-
-  private:
-    SeparateArrayInitTraverser();
-    bool visitDeclaration(Visit, TIntermDeclaration *node) override;
-};
-
-void SeparateArrayInitTraverser::apply(TIntermNode *root)
-{
-    SeparateArrayInitTraverser separateInit;
-    root->traverse(&separateInit);
-    separateInit.updateTree();
-}
-
-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.push_back(
-                NodeReplaceWithMultipleEntry(parentBlock, node, replacements));
-        }
-    }
-    return false;
-}
-
-}  // namespace
-
-void SeparateArrayInitialization(TIntermNode *root)
-{
-    SeparateArrayInitTraverser::apply(root);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/SeparateArrayInitialization.h
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// 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_SEPARATEARRAYINITIALIZATION_H_
-#define COMPILER_TRANSLATOR_SEPARATEARRAYINITIALIZATION_H_
-
-namespace sh
-{
-class TIntermNode;
-
-void SeparateArrayInitialization(TIntermNode *root);
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_SEPARATEARRAYINITIALIZATION_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/SeparateDeclarations.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// 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/SeparateDeclarations.h"
-
-#include "compiler/translator/IntermTraverse.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class SeparateDeclarationsTraverser : private TIntermTraverser
-{
-  public:
-    static void apply(TIntermNode *root);
-
-  private:
-    SeparateDeclarationsTraverser();
-    bool visitDeclaration(Visit, TIntermDeclaration *node) override;
-};
-
-void SeparateDeclarationsTraverser::apply(TIntermNode *root)
-{
-    SeparateDeclarationsTraverser separateDecl;
-    root->traverse(&separateDecl);
-    separateDecl.updateTree();
-}
-
-SeparateDeclarationsTraverser::SeparateDeclarationsTraverser()
-    : TIntermTraverser(true, false, false)
-{
-}
-
-bool SeparateDeclarationsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
-{
-    TIntermSequence *sequence = node->getSequence();
-    if (sequence->size() > 1)
-    {
-        TIntermBlock *parentBlock = getParentNode()->getAsBlock();
-        ASSERT(parentBlock != nullptr);
-
-        TIntermSequence replacementDeclarations;
-        for (size_t ii = 0; ii < sequence->size(); ++ii)
-        {
-            TIntermDeclaration *replacementDeclaration = new TIntermDeclaration();
-
-            replacementDeclaration->appendDeclarator(sequence->at(ii)->getAsTyped());
-            replacementDeclaration->setLine(sequence->at(ii)->getLine());
-            replacementDeclarations.push_back(replacementDeclaration);
-        }
-
-        mMultiReplacements.push_back(
-            NodeReplaceWithMultipleEntry(parentBlock, node, replacementDeclarations));
-    }
-    return false;
-}
-
-}  // namespace
-
-void SeparateDeclarations(TIntermNode *root)
-{
-    SeparateDeclarationsTraverser::apply(root);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/SeparateDeclarations.h
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// 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_SEPARATEDECLARATIONS_H_
-#define COMPILER_TRANSLATOR_SEPARATEDECLARATIONS_H_
-
-namespace sh
-{
-class TIntermNode;
-
-void SeparateDeclarations(TIntermNode *root);
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_SEPARATEDECLARATIONS_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/SeparateExpressionsReturningArrays.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// 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/SeparateExpressionsReturningArrays.h"
-
-#include "compiler/translator/IntermNodePatternMatcher.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/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
-
-void SeparateExpressionsReturningArrays(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())
-            traverser.updateTree();
-    } while (traverser.foundArrayExpression());
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/SeparateExpressionsReturningArrays.h
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// 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_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_
-#define COMPILER_TRANSLATOR_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_
-
-namespace sh
-{
-class TIntermNode;
-class TSymbolTable;
-
-void SeparateExpressionsReturningArrays(TIntermNode *root, TSymbolTable *symbolTable);
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_
--- a/gfx/angle/checkout/src/compiler/translator/ShaderVars.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/ShaderVars.cpp
@@ -27,27 +27,27 @@ InterpolationType GetNonAuxiliaryInterpo
 // 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()
-    : type(0), precision(0), flattenedOffsetInParentArrays(0), staticUse(false)
+    : type(0), precision(0), flattenedOffsetInParentArrays(0), staticUse(false), active(false)
 {
 }
 
 ShaderVariable::ShaderVariable(GLenum typeIn)
-    : type(typeIn), precision(0), flattenedOffsetInParentArrays(0), staticUse(false)
+    : type(typeIn), precision(0), flattenedOffsetInParentArrays(0), staticUse(false), active(false)
 {
 }
 
 ShaderVariable::ShaderVariable(GLenum typeIn, unsigned int arraySizeIn)
-    : type(typeIn), precision(0), flattenedOffsetInParentArrays(0), staticUse(false)
+    : type(typeIn), precision(0), flattenedOffsetInParentArrays(0), staticUse(false), active(false)
 {
     ASSERT(arraySizeIn != 0);
     arraySizes.push_back(arraySizeIn);
 }
 
 ShaderVariable::~ShaderVariable()
 {
 }
@@ -55,41 +55,43 @@ ShaderVariable::~ShaderVariable()
 ShaderVariable::ShaderVariable(const ShaderVariable &other)
     : type(other.type),
       precision(other.precision),
       name(other.name),
       mappedName(other.mappedName),
       arraySizes(other.arraySizes),
       flattenedOffsetInParentArrays(other.flattenedOffsetInParentArrays),
       staticUse(other.staticUse),
+      active(other.active),
       fields(other.fields),
       structName(other.structName)
 {
 }
 
 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;
     flattenedOffsetInParentArrays = other.flattenedOffsetInParentArrays;
     fields     = other.fields;
     structName = other.structName;
     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 || fields.size() != other.fields.size() ||
-        structName != other.structName)
+        staticUse != other.staticUse || active != other.active ||
+        fields.size() != other.fields.size() || structName != other.structName)
     {
         return false;
     }
     for (size_t ii = 0; ii < fields.size(); ++ii)
     {
         if (fields[ii] != other.fields[ii])
             return false;
     }
@@ -449,16 +451,17 @@ bool Varying::isSameVaryingAtLinkTime(co
 }
 
 InterfaceBlock::InterfaceBlock()
     : arraySize(0),
       layout(BLOCKLAYOUT_PACKED),
       isRowMajorLayout(false),
       binding(-1),
       staticUse(false),
+      active(false),
       blockType(BlockType::BLOCK_UNIFORM)
 {
 }
 
 InterfaceBlock::~InterfaceBlock()
 {
 }
 
@@ -466,31 +469,33 @@ InterfaceBlock::InterfaceBlock(const Int
     : 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;
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/SimplifyLoopConditions.cpp
+++ /dev/null
@@ -1,300 +0,0 @@
-//
-// Copyright (c) 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/SimplifyLoopConditions.h"
-
-#include "compiler/translator/IntermNodePatternMatcher.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/StaticType.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class SimplifyLoopConditionsTraverser : public TLValueTrackingTraverser
-{
-  public:
-    SimplifyLoopConditionsTraverser(unsigned int conditionsToSimplifyMask,
-                                    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 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;
-    IntermNodePatternMatcher mConditionsToSimplify;
-};
-
-SimplifyLoopConditionsTraverser::SimplifyLoopConditionsTraverser(
-    unsigned int conditionsToSimplifyMask,
-    TSymbolTable *symbolTable)
-    : TLValueTrackingTraverser(true, false, false, symbolTable),
-      mFoundLoopToChange(false),
-      mInsideLoopInitConditionOrExpression(false),
-      mConditionsToSimplify(conditionsToSimplifyMask)
-{
-}
-
-// 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.
-
-    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.
-
-    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.
-
-    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.
-
-    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.
-
-    mFoundLoopToChange = mConditionsToSimplify.match(node);
-    return !mFoundLoopToChange;
-}
-
-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                   = false;
-
-    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;
-
-    if (mFoundLoopToChange)
-    {
-        const TType *boolType        = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
-        TVariable *conditionVariable = CreateTempVariable(mSymbolTable, boolType);
-
-        // Replace the loop condition with a boolean variable that's updated on each iteration.
-        TLoopType loopType = node->getType();
-        if (loopType == ELoopWhile)
-        {
-            // Transform:
-            //   while (expr) { body; }
-            // into
-            //   bool s0 = expr;
-            //   while (s0) { { body; } s0 = expr; }
-            TIntermDeclaration *tempInitDeclaration =
-                CreateTempInitDeclarationNode(conditionVariable, node->getCondition()->deepCopy());
-            insertStatementInParentBlock(tempInitDeclaration);
-
-            TIntermBlock *newBody = new TIntermBlock();
-            if (node->getBody())
-            {
-                newBody->getSequence()->push_back(node->getBody());
-            }
-            newBody->getSequence()->push_back(
-                CreateTempAssignmentNode(conditionVariable, node->getCondition()->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(conditionVariable));
-        }
-        else if (loopType == ELoopDoWhile)
-        {
-            // Transform:
-            //   do {
-            //     body;
-            //   } while (expr);
-            // into
-            //   bool s0 = true;
-            //   do {
-            //     { body; }
-            //     s0 = expr;
-            //   } while (s0);
-            TIntermDeclaration *tempInitDeclaration =
-                CreateTempInitDeclarationNode(conditionVariable, CreateBoolNode(true));
-            insertStatementInParentBlock(tempInitDeclaration);
-
-            TIntermBlock *newBody = new TIntermBlock();
-            if (node->getBody())
-            {
-                newBody->getSequence()->push_back(node->getBody());
-            }
-            newBody->getSequence()->push_back(
-                CreateTempAssignmentNode(conditionVariable, node->getCondition()->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(conditionVariable));
-        }
-        else if (loopType == ELoopFor)
-        {
-            // Move the loop condition inside the loop.
-            // Transform:
-            //   for (init; expr; exprB) { body; }
-            // into
-            //   {
-            //     init;
-            //     bool s0 = expr;
-            //     while (s0) {
-            //       { body; }
-            //       exprB;
-            //       s0 = expr;
-            //     }
-            //   }
-            TIntermBlock *loopScope            = new TIntermBlock();
-            TIntermSequence *loopScopeSequence = loopScope->getSequence();
-
-            // Insert "init;"
-            if (node->getInit())
-            {
-                loopScopeSequence->push_back(node->getInit());
-            }
-
-            // Insert "bool s0 = expr;" if applicable, "bool s0 = true;" otherwise
-            TIntermTyped *conditionInitializer = nullptr;
-            if (node->getCondition())
-            {
-                conditionInitializer = node->getCondition()->deepCopy();
-            }
-            else
-            {
-                conditionInitializer = CreateBoolNode(true);
-            }
-            loopScopeSequence->push_back(
-                CreateTempInitDeclarationNode(conditionVariable, conditionInitializer));
-
-            // Insert "{ body; }" in the while loop
-            TIntermBlock *whileLoopBody = new TIntermBlock();
-            if (node->getBody())
-            {
-                whileLoopBody->getSequence()->push_back(node->getBody());
-            }
-            // Insert "exprB;" in the while loop
-            if (node->getExpression())
-            {
-                whileLoopBody->getSequence()->push_back(node->getExpression());
-            }
-            // Insert "s0 = expr;" in the while loop
-            if (node->getCondition())
-            {
-                whileLoopBody->getSequence()->push_back(
-                    CreateTempAssignmentNode(conditionVariable, node->getCondition()->deepCopy()));
-            }
-
-            // Create "while(s0) { whileLoopBody }"
-            TIntermLoop *whileLoop =
-                new TIntermLoop(ELoopWhile, nullptr, CreateTempSymbolNode(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);
-}
-
-}  // namespace
-
-void SimplifyLoopConditions(TIntermNode *root,
-                            unsigned int conditionsToSimplifyMask,
-                            TSymbolTable *symbolTable)
-{
-    SimplifyLoopConditionsTraverser traverser(conditionsToSimplifyMask, symbolTable);
-    root->traverse(&traverser);
-    traverser.updateTree();
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/SimplifyLoopConditions.h
+++ /dev/null
@@ -1,24 +0,0 @@
-//
-// Copyright (c) 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_SIMPLIFYLOOPCONDITIONS_H_
-#define COMPILER_TRANSLATOR_SIMPLIFYLOOPCONDITIONS_H_
-
-namespace sh
-{
-class TIntermNode;
-class TSymbolTable;
-
-void SimplifyLoopConditions(TIntermNode *root,
-                            unsigned int conditionsToSimplify,
-                            TSymbolTable *symbolTable);
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_SIMPLIFYLOOPCONDITIONS_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/SplitSequenceOperator.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-//
-// Copyright (c) 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/SplitSequenceOperator.h"
-
-#include "compiler/translator/IntermNodePatternMatcher.h"
-#include "compiler/translator/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
-
-void SplitSequenceOperator(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())
-            traverser.updateTree();
-    } while (traverser.foundExpressionToSplit());
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/SplitSequenceOperator.h
+++ /dev/null
@@ -1,25 +0,0 @@
-//
-// Copyright (c) 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_SPLITSEQUENCEOPERATOR_H_
-#define COMPILER_TRANSLATOR_SPLITSEQUENCEOPERATOR_H_
-
-namespace sh
-{
-
-class TIntermNode;
-class TSymbolTable;
-
-void SplitSequenceOperator(TIntermNode *root, int patternsToSplitMask, TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_SPLITSEQUENCEOPERATOR_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/StaticType.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-//
-// Copyright (c) 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.
-//
-
-#include "compiler/translator/StaticType.h"
-
-namespace sh
-{
-
-namespace StaticType
-{
-
-const TType *GetForFloatImage(TBasicType basicType)
-{
-    switch (basicType)
-    {
-        case EbtGImage2D:
-            return Get<EbtImage2D, EbpUndefined, EvqGlobal, 1, 1>();
-        case EbtGImage3D:
-            return Get<EbtImage3D, EbpUndefined, EvqGlobal, 1, 1>();
-        case EbtGImage2DArray:
-            return Get<EbtImage2DArray, EbpUndefined, EvqGlobal, 1, 1>();
-        case EbtGImageCube:
-            return Get<EbtImageCube, EbpUndefined, EvqGlobal, 1, 1>();
-        default:
-            UNREACHABLE();
-            return GetBasic<EbtVoid>();
-    }
-}
-
-const TType *GetForIntImage(TBasicType basicType)
-{
-    switch (basicType)
-    {
-        case EbtGImage2D:
-            return Get<EbtIImage2D, EbpUndefined, EvqGlobal, 1, 1>();
-        case EbtGImage3D:
-            return Get<EbtIImage3D, EbpUndefined, EvqGlobal, 1, 1>();
-        case EbtGImage2DArray:
-            return Get<EbtIImage2DArray, EbpUndefined, EvqGlobal, 1, 1>();
-        case EbtGImageCube:
-            return Get<EbtIImageCube, EbpUndefined, EvqGlobal, 1, 1>();
-        default:
-            UNREACHABLE();
-            return GetBasic<EbtVoid>();
-    }
-}
-
-const TType *GetForUintImage(TBasicType basicType)
-{
-    switch (basicType)
-    {
-        case EbtGImage2D:
-            return Get<EbtUImage2D, EbpUndefined, EvqGlobal, 1, 1>();
-        case EbtGImage3D:
-            return Get<EbtUImage3D, EbpUndefined, EvqGlobal, 1, 1>();
-        case EbtGImage2DArray:
-            return Get<EbtUImage2DArray, EbpUndefined, EvqGlobal, 1, 1>();
-        case EbtGImageCube:
-            return Get<EbtUImageCube, EbpUndefined, EvqGlobal, 1, 1>();
-        default:
-            UNREACHABLE();
-            return GetBasic<EbtVoid>();
-    }
-}
-
-}  // namespace StaticType
-
-}  // namespace sh
--- a/gfx/angle/checkout/src/compiler/translator/StaticType.h
+++ b/gfx/angle/checkout/src/compiler/translator/StaticType.h
@@ -20,70 +20,39 @@ namespace StaticType
 
 namespace Helpers
 {
 
 //
 // Generation and static allocation of type mangled name values.
 //
 
-// Size of the maximum possible constexpr-generated mangled name.
+// Size of the constexpr-generated mangled name.
 // If this value is too small, the compiler will produce errors.
-static constexpr size_t kStaticMangledNameMaxLength = 10;
+static constexpr size_t kStaticMangledNameLength = 2;
 
 // 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[kStaticMangledNameMaxLength + 1] = {};
+    char name[kStaticMangledNameLength + 1] = {};
 };
 
 // Generates a mangled name for a TType given its parameters.
 constexpr StaticMangledName BuildStaticMangledName(TBasicType basicType,
                                                    TPrecision precision,
                                                    TQualifier qualifier,
                                                    unsigned char primarySize,
                                                    unsigned char secondarySize)
 {
     StaticMangledName name = {};
-    // When this function is executed constexpr (should be always),
-    // name.name[at] is guaranteed by the compiler to never go out of bounds.
-    size_t at = 0;
-
-    bool isMatrix = primarySize > 1 && secondarySize > 1;
-    bool isVector = primarySize > 1 && secondarySize == 1;
-
-    if (isMatrix)
-    {
-        name.name[at++] = 'm';
-    }
-    else if (isVector)
-    {
-        name.name[at++] = 'v';
-    }
-
-    {
-        const char *basicMangledName = GetBasicMangledName(basicType);
-        for (size_t i = 0; basicMangledName[i] != '\0'; ++i)
-        {
-            name.name[at++] = basicMangledName[i];
-        }
-    }
-
-    name.name[at++] = '0' + primarySize;
-    if (isMatrix)
-    {
-        name.name[at++] = 'x';
-        name.name[at++] = '0' + secondarySize;
-    }
-
-    name.name[at++] = ';';
-
-    name.name[at] = '\0';
+    name.name[0]           = TType::GetSizeMangledName(primarySize, secondarySize);
+    name.name[1]           = GetBasicMangledName(basicType);
+    name.name[2]           = '\0';
     return name;
 }
 
 // This "variable" contains the mangled names for every constexpr-generated TType.
 // If kMangledNameInstance<B, P, Q, PS, SS> is used anywhere (specifally
 // in kInstance, below), this is where the appropriate type will be stored.
 template <TBasicType basicType,
           TPrecision precision,
@@ -217,19 +186,13 @@ constexpr const TType *GetForVec(TQualif
         case EvqOut:
             return Helpers::GetForVecMatHelper<basicType, precision, EvqOut, 1>(size);
         default:
             UNREACHABLE();
             return GetBasic<EbtVoid>();
     }
 }
 
-const TType *GetForFloatImage(TBasicType basicType);
-
-const TType *GetForIntImage(TBasicType basicType);
-
-const TType *GetForUintImage(TBasicType basicType);
-
 }  // namespace StaticType
 
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_STATIC_TYPE_H_
--- a/gfx/angle/checkout/src/compiler/translator/Symbol.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/Symbol.cpp
@@ -41,21 +41,23 @@ TSymbol::TSymbol(TSymbolTable *symbolTab
 {
     ASSERT(mSymbolType == SymbolType::BuiltIn || mExtension == TExtension::UNDEFINED);
     ASSERT(mName != "" || mSymbolType == SymbolType::AngleInternal ||
            mSymbolType == SymbolType::Empty);
 }
 
 ImmutableString TSymbol::name() const
 {
-    if (mName != "")
+    if (!mName.empty())
     {
         return mName;
     }
-    ASSERT(mSymbolType == SymbolType::AngleInternal);
+    // 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
@@ -77,16 +79,24 @@ TVariable::TVariable(TSymbolTable *symbo
 TStructure::TStructure(TSymbolTable *symbolTable,
                        const ImmutableString &name,
                        const TFieldList *fields,
                        SymbolType symbolType)
     : TSymbol(symbolTable, name, symbolType), TFieldListCollection(fields)
 {
 }
 
+TStructure::TStructure(const TSymbolUniqueId &id,
+                       const ImmutableString &name,
+                       TExtension extension,
+                       const TFieldList *fields)
+    : TSymbol(id, name, SymbolType::BuiltIn, extension), 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)
@@ -119,16 +129,27 @@ TInterfaceBlock::TInterfaceBlock(TSymbol
     : TSymbol(symbolTable, name, symbolType, extension),
       TFieldListCollection(fields),
       mBlockStorage(layoutQualifier.blockStorage),
       mBinding(layoutQualifier.binding)
 {
     ASSERT(name != nullptr);
 }
 
+TInterfaceBlock::TInterfaceBlock(const TSymbolUniqueId &id,
+                                 const ImmutableString &name,
+                                 TExtension extension,
+                                 const TFieldList *fields)
+    : TSymbol(id, name, SymbolType::BuiltIn, extension),
+      TFieldListCollection(fields),
+      mBlockStorage(EbsUnspecified),
+      mBinding(0)
+{
+}
+
 TFunction::TFunction(TSymbolTable *symbolTable,
                      const ImmutableString &name,
                      SymbolType symbolType,
                      const TType *retType,
                      bool knownToNotHaveSideEffects)
     : TSymbol(symbolTable, name, symbolType, TExtension::UNDEFINED),
       mParametersVector(new TParamVector()),
       mParameters(nullptr),
@@ -140,42 +161,17 @@ TFunction::TFunction(TSymbolTable *symbo
       mHasPrototypeDeclaration(false),
       mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
 {
     // Functions with an empty name are not allowed.
     ASSERT(symbolType != SymbolType::Empty);
     ASSERT(name != nullptr || symbolType == SymbolType::AngleInternal);
 }
 
-TFunction::TFunction(TSymbolTable *symbolTable,
-                     const ImmutableString &name,
-                     TExtension extension,
-                     TConstParameter *parameters,
-                     size_t paramCount,
-                     const TType *retType,
-                     TOperator op,
-                     bool knownToNotHaveSideEffects)
-    : TSymbol(symbolTable, name, SymbolType::BuiltIn, extension),
-      mParametersVector(nullptr),
-      mParameters(parameters),
-      mParamCount(paramCount),
-      returnType(retType),
-      mMangledName(""),
-      mOp(op),
-      defined(false),
-      mHasPrototypeDeclaration(false),
-      mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
-{
-    ASSERT(name != nullptr);
-    ASSERT(op != EOpNull);
-    ASSERT(paramCount == 0 || parameters != nullptr);
-    mMangledName = buildMangledName();
-}
-
-void TFunction::addParameter(const TConstParameter &p)
+void TFunction::addParameter(const TVariable *p)
 {
     ASSERT(mParametersVector);
     mParametersVector->push_back(p);
     mParameters  = mParametersVector->data();
     mParamCount  = mParametersVector->size();
     mMangledName = ImmutableString("");
 }
 
@@ -190,17 +186,17 @@ void TFunction::shareParameters(const TF
 
 ImmutableString TFunction::buildMangledName() const
 {
     std::string newName(name().data(), name().length());
     newName += kFunctionMangledNameSeparator;
 
     for (size_t i = 0u; i < mParamCount; ++i)
     {
-        newName += mParameters[i].type->getMangledName();
+        newName += mParameters[i]->getType().getMangledName();
     }
     return ImmutableString(newName);
 }
 
 bool TFunction::isMain() const
 {
     return symbolType() == SymbolType::UserDefined && name() == kMainName;
 }
--- a/gfx/angle/checkout/src/compiler/translator/Symbol.h
+++ b/gfx/angle/checkout/src/compiler/translator/Symbol.h
@@ -37,18 +37,20 @@ class TSymbol : angle::NonCopyable
             const ImmutableString &name,
             SymbolType symbolType,
             TExtension extension = TExtension::UNDEFINED);
 
     // Note that we don't have a virtual destructor in order to support constexpr symbols. Data is
     // either statically allocated or pool allocated.
     ~TSymbol() = default;
 
-    // Don't call name() or getMangledName() for empty symbols (symbolType == SymbolType::Empty).
+    // 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).
     virtual ImmutableString getMangledName() const;
 
     virtual bool isFunction() const { return false; }
     virtual bool isVariable() const { return false; }
     virtual bool isStruct() const { return false; }
 
     const TSymbolUniqueId &uniqueId() const { return mUniqueId; }
     SymbolType symbolType() const { return mSymbolType; }
@@ -84,26 +86,27 @@ class TVariable : public TSymbol
 
     bool isVariable() const override { return true; }
     const TType &getType() const { return *mType; }
 
     const TConstantUnion *getConstPointer() const { return unionArray; }
 
     void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; }
 
-  private:
+    // 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, extension), mType(type), unionArray(nullptr)
     {
     }
 
+  private:
     const TType *mType;
     const TConstantUnion *unionArray;
 };
 
 // Struct type.
 class TStructure : public TSymbol, public TFieldListCollection
 {
   public:
@@ -120,16 +123,23 @@ class TStructure : public TSymbol, publi
                               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);
+
     // 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 RegenerateStructNames;
     void setName(const ImmutableString &name);
 
     bool mAtGlobalScope;
 };
@@ -145,54 +155,43 @@ class TInterfaceBlock : public TSymbol, 
                     const TLayoutQualifier &layoutQualifier,
                     SymbolType symbolType,
                     TExtension extension = TExtension::UNDEFINED);
 
     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);
+
     TLayoutBlockStorage mBlockStorage;
     int mBinding;
 
     // Note that we only record matrix packing on a per-field granularity.
 };
 
-// Immutable version of TParameter.
-struct TConstParameter
-{
-    POOL_ALLOCATOR_NEW_DELETE();
-    TConstParameter() : name(""), type(nullptr) {}
-    explicit TConstParameter(const ImmutableString &n) : name(n), type(nullptr) {}
-    constexpr explicit TConstParameter(const TType *t) : name(""), type(t) {}
-    TConstParameter(const ImmutableString &n, const TType *t) : name(n), type(t) {}
-
-    // Both constructor arguments must be const.
-    TConstParameter(ImmutableString *n, TType *t)       = delete;
-    TConstParameter(const ImmutableString *n, TType *t) = delete;
-    TConstParameter(ImmutableString *n, const TType *t) = delete;
-
-    const ImmutableString name;
-    const TType *const type;
-};
-
-// The function sub-class of symbols and the parser will need to
-// share this definition of a function parameter.
+// Parameter class used for parsing user-defined function parameters.
 struct TParameter
 {
-    // Destructively converts to TConstParameter.
+    // Destructively converts to TVariable.
     // This method resets name and type to nullptrs to make sure
     // their content cannot be modified after the call.
-    TConstParameter turnToConst()
+    const TVariable *createVariable(TSymbolTable *symbolTable)
     {
         const ImmutableString constName(name);
         const TType *constType   = type;
         name                     = nullptr;
         type                     = nullptr;
-        return TConstParameter(constName, constType);
+        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
@@ -200,85 +199,76 @@ class TFunction : public TSymbol
   public:
     // User-defined function
     TFunction(TSymbolTable *symbolTable,
               const ImmutableString &name,
               SymbolType symbolType,
               const TType *retType,
               bool knownToNotHaveSideEffects);
 
-    // Built-in function
-    TFunction(TSymbolTable *symbolTable,
-              const ImmutableString &name,
-              TExtension extension,
-              TConstParameter *parameters,
-              size_t paramCount,
-              const TType *retType,
-              TOperator op,
-              bool knownToNotHaveSideEffects);
-
     bool isFunction() const override { return true; }
 
-    void addParameter(const TConstParameter &p);
+    void addParameter(const TVariable *p);
     void shareParameters(const TFunction &parametersSource);
 
     ImmutableString getMangledName() const override
     {
-        if (mMangledName == "")
+        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() { return defined; }
     void setHasPrototypeDeclaration() { mHasPrototypeDeclaration = true; }
     bool hasPrototypeDeclaration() const { return mHasPrototypeDeclaration; }
 
     size_t getParamCount() const { return mParamCount; }
-    const TConstParameter &getParam(size_t i) const { return mParameters[i]; }
+    const TVariable *getParam(size_t i) const { return mParameters[i]; }
 
     bool isKnownToNotHaveSideEffects() const { return mKnownToNotHaveSideEffects; }
 
     bool isMain() const;
     bool isImageFunction() const;
 
-  private:
+    // Note: Only to be used for static built-in functions!
     constexpr TFunction(const TSymbolUniqueId &id,
                         const ImmutableString &name,
                         TExtension extension,
-                        const TConstParameter *parameters,
+                        const TVariable *const *parameters,
                         size_t paramCount,
                         const TType *retType,
-                        const ImmutableString &mangledName,
                         TOperator op,
                         bool knownToNotHaveSideEffects)
         : TSymbol(id, name, SymbolType::BuiltIn, extension),
           mParametersVector(nullptr),
           mParameters(parameters),
           mParamCount(paramCount),
           returnType(retType),
-          mMangledName(mangledName),
+          mMangledName(nullptr),
           mOp(op),
           defined(false),
           mHasPrototypeDeclaration(false),
           mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
     {
     }
 
+  private:
     ImmutableString buildMangledName() const;
 
-    typedef TVector<TConstParameter> TParamVector;
+    typedef TVector<const TVariable *> TParamVector;
     TParamVector *mParametersVector;
-    const TConstParameter *mParameters;
+    const TVariable *const *mParameters;
     size_t mParamCount;
     const TType *const returnType;
     mutable ImmutableString mMangledName;
     const TOperator mOp;  // Only set for built-ins
     bool defined;
     bool mHasPrototypeDeclaration;
     bool mKnownToNotHaveSideEffects;
 };
--- a/gfx/angle/checkout/src/compiler/translator/SymbolTable.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolTable.cpp
@@ -53,40 +53,16 @@ class TSymbolTable::TSymbolTableLevel
     using tInsertResult = std::pair<tLevel::iterator, bool>;
 
     tLevel level;
 
     std::set<ImmutableString> mInvariantVaryings;
     bool mGlobalInvariant;
 };
 
-class TSymbolTable::TSymbolTableBuiltInLevel
-{
-  public:
-    TSymbolTableBuiltInLevel() = default;
-
-    bool insert(const TSymbol *symbol);
-
-    const TSymbol *find(const ImmutableString &name) const;
-
-    void insertUnmangledBuiltIn(const char *name, TExtension ext);
-    const UnmangledBuiltIn *getUnmangledBuiltIn(const ImmutableString &name) const;
-
-  private:
-    using tLevel        = TUnorderedMap<ImmutableString,
-                                 const TSymbol *,
-                                 ImmutableString::FowlerNollVoHash<sizeof(size_t)>>;
-    using tLevelPair    = const tLevel::value_type;
-    using tInsertResult = std::pair<tLevel::iterator, bool>;
-
-    tLevel mLevel;
-
-    std::map<ImmutableString, UnmangledBuiltIn> mUnmangledBuiltIns;
-};
-
 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)
@@ -98,64 +74,31 @@ TSymbol *TSymbolTable::TSymbolTableLevel
 {
     tLevel::const_iterator it = level.find(name);
     if (it == level.end())
         return nullptr;
     else
         return (*it).second;
 }
 
-bool TSymbolTable::TSymbolTableBuiltInLevel::insert(const TSymbol *symbol)
-{
-    // returning true means symbol was added to the table
-    tInsertResult result = mLevel.insert(tLevelPair(symbol->getMangledName(), symbol));
-    return result.second;
-}
-
-const TSymbol *TSymbolTable::TSymbolTableBuiltInLevel::find(const ImmutableString &name) const
-{
-    tLevel::const_iterator it = mLevel.find(name);
-    if (it == mLevel.end())
-        return nullptr;
-    else
-        return (*it).second;
-}
-
-void TSymbolTable::TSymbolTableBuiltInLevel::insertUnmangledBuiltIn(const char *name,
-                                                                    TExtension ext)
-{
-    ImmutableString immName(name);
-    if (ext == TExtension::UNDEFINED ||
-        mUnmangledBuiltIns.find(immName) == mUnmangledBuiltIns.end())
-    {
-        mUnmangledBuiltIns[immName] = UnmangledBuiltIn(ext);
-    }
-}
-
-const UnmangledBuiltIn *TSymbolTable::TSymbolTableBuiltInLevel::getUnmangledBuiltIn(
-    const ImmutableString &name) const
-{
-    auto it = mUnmangledBuiltIns.find(ImmutableString(name));
-    if (it == mUnmangledBuiltIns.end())
-    {
-        return nullptr;
-    }
-    return &(it->second);
-}
-
-TSymbolTable::TSymbolTable() : mUniqueIdCounter(0), mUserDefinedUniqueIdsStart(-1)
+TSymbolTable::TSymbolTable()
+    : mUniqueIdCounter(0), mShaderType(GL_FRAGMENT_SHADER), mGlInVariableWithArraySize(nullptr)
 {
 }
 
 TSymbolTable::~TSymbolTable() = default;
 
-void TSymbolTable::pushBuiltInLevel()
+bool TSymbolTable::isEmpty() const
 {
-    mBuiltInTable.push_back(
-        std::unique_ptr<TSymbolTableBuiltInLevel>(new TSymbolTableBuiltInLevel));
+    return mTable.empty();
+}
+
+bool TSymbolTable::atGlobalLevel() const
+{
+    return mTable.size() == 1u;
 }
 
 void TSymbolTable::push()
 {
     mTable.push_back(std::unique_ptr<TSymbolTableLevel>(new TSymbolTableLevel));
     mPrecisionStack.push_back(std::unique_ptr<PrecisionStackLevel>(new PrecisionStackLevel));
 }
 
@@ -190,506 +133,124 @@ const TFunction *TSymbolTable::setFuncti
         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 = mVar_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 mVar_gl_FragData;
+}
+
+const TVariable *TSymbolTable::gl_SecondaryFragDataEXT() const
+{
+    return mVar_gl_SecondaryFragDataEXT;
+}
+
+void TSymbolTable::markStaticWrite(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;
+    }
+    iter->second.staticWrite = true;
+}
+
+void TSymbolTable::markStaticRead(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;
+    }
+    iter->second.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();
+}
+
 const TSymbol *TSymbolTable::find(const ImmutableString &name, int shaderVersion) 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 findBuiltIn(name, shaderVersion, false);
+    return findBuiltIn(name, shaderVersion);
 }
 
 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::findBuiltIn(const ImmutableString &name, int shaderVersion) const
-{
-    return findBuiltIn(name, shaderVersion, false);
-}
-
-const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name,
-                                         int shaderVersion,
-                                         bool includeGLSLBuiltins) const
-{
-    for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
-    {
-        if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
-            level--;
-        if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
-            level--;
-        if (level == ESSL3_BUILTINS && shaderVersion < 300)
-            level--;
-        if (level == ESSL1_BUILTINS && shaderVersion != 100)
-            level--;
-
-        const TSymbol *symbol = mBuiltInTable[level]->find(name);
-
-        if (symbol)
-            return symbol;
-    }
-
-    return nullptr;
-}
-
-constexpr bool IsGenType(const TType *type)
-{
-    if (type)
-    {
-        TBasicType basicType = type->getBasicType();
-        return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
-               basicType == EbtGenBType;
-    }
-
-    return false;
-}
-
-constexpr bool IsVecType(const TType *type)
-{
-    if (type)
-    {
-        TBasicType basicType = type->getBasicType();
-        return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
-               basicType == EbtBVec;
-    }
-
-    return false;
-}
-
-constexpr const TType *SpecificType(const TType *type, int size)
+bool TSymbolTable::declare(TSymbol *symbol)
 {
-    ASSERT(size >= 1 && size <= 4);
-
-    if (!type)
-    {
-        return nullptr;
-    }
-
-    ASSERT(!IsVecType(type));
-
-    switch (type->getBasicType())
-    {
-        case EbtGenType:
-            return StaticType::GetForVec<EbtFloat>(type->getQualifier(),
-                                                            static_cast<unsigned char>(size));
-        case EbtGenIType:
-            return StaticType::GetForVec<EbtInt>(type->getQualifier(),
-                                                          static_cast<unsigned char>(size));
-        case EbtGenUType:
-            return StaticType::GetForVec<EbtUInt>(type->getQualifier(),
-                                                           static_cast<unsigned char>(size));
-        case EbtGenBType:
-            return StaticType::GetForVec<EbtBool>(type->getQualifier(),
-                                                           static_cast<unsigned char>(size));
-        default:
-            return type;
-    }
-}
-
-constexpr const TType *VectorType(const TType *type, int size)
-{
-    ASSERT(size >= 2 && size <= 4);
-
-    if (!type)
-    {
-        return nullptr;
-    }
-
-    ASSERT(!IsGenType(type));
-
-    switch (type->getBasicType())
-    {
-        case EbtVec:
-            return StaticType::GetForVecMat<EbtFloat>(static_cast<unsigned char>(size));
-        case EbtIVec:
-            return StaticType::GetForVecMat<EbtInt>(static_cast<unsigned char>(size));
-        case EbtUVec:
-            return StaticType::GetForVecMat<EbtUInt>(static_cast<unsigned char>(size));
-        case EbtBVec:
-            return StaticType::GetForVecMat<EbtBool>(static_cast<unsigned char>(size));
-        default:
-            return type;
-    }
-}
-
-bool TSymbolTable::declareVariable(TVariable *variable)
-{
-    ASSERT(variable->symbolType() == SymbolType::UserDefined);
-    return insertVariable(currentLevel(), variable);
-}
-
-bool TSymbolTable::declareStructType(TStructure *str)
-{
-    return insertStructType(currentLevel(), str);
-}
-
-bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock)
-{
-    return insert(currentLevel(), interfaceBlock);
+    ASSERT(!mTable.empty());
+    ASSERT(symbol->symbolType() == SymbolType::UserDefined);
+    ASSERT(!symbol->isFunction());
+    return mTable.back()->insert(symbol);
 }
 
 void TSymbolTable::declareUserDefinedFunction(TFunction *function, bool insertUnmangledName)
 {
-    ASSERT(currentLevel() >= GLOBAL_LEVEL);
+    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);
 }
 
-TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
-                                        const ImmutableString &name,
-                                        const TType *type)
-{
-    ASSERT(level <= LAST_BUILTIN_LEVEL);
-    ASSERT(type->isRealized());
-    return insertVariable(level, name, type, SymbolType::BuiltIn);
-}
-
-TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
-                                        const ImmutableString &name,
-                                        const TType *type,
-                                        SymbolType symbolType)
-{
-    ASSERT(level > LAST_BUILTIN_LEVEL || type->isRealized());
-    TVariable *var = new TVariable(this, name, type, symbolType);
-    if (insert(level, var))
-    {
-        return var;
-    }
-    return nullptr;
-}
-
-void TSymbolTable::insertVariableExt(ESymbolLevel level,
-                                     TExtension ext,
-                                     const ImmutableString &name,
-                                     const TType *type)
-{
-    ASSERT(level <= LAST_BUILTIN_LEVEL);
-    ASSERT(type->isRealized());
-    TVariable *var = new TVariable(this, name, type, SymbolType::BuiltIn, ext);
-    bool inserted  = insert(level, var);
-    UNUSED_VARIABLE(inserted);
-    ASSERT(inserted);
-}
-
-bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable)
-{
-    ASSERT(variable);
-    ASSERT(level > LAST_BUILTIN_LEVEL || variable->getType().isRealized());
-    return insert(level, variable);
-}
-
-bool TSymbolTable::insert(ESymbolLevel level, TSymbol *symbol)
-{
-    ASSERT(level > LAST_BUILTIN_LEVEL || mUserDefinedUniqueIdsStart == -1);
-    if (level <= LAST_BUILTIN_LEVEL)
-    {
-        return mBuiltInTable[level]->insert(symbol);
-    }
-    else
-    {
-        return mTable[level - LAST_BUILTIN_LEVEL - 1]->insert(symbol);
-    }
-}
-
-bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
-{
-    ASSERT(str);
-    return insert(level, str);
-}
-
-bool TSymbolTable::insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock)
-{
-    ASSERT(interfaceBlock);
-    return insert(level, interfaceBlock);
-}
-
-template <TPrecision precision>
-bool TSymbolTable::insertConstInt(ESymbolLevel level, const ImmutableString &name, int value)
-{
-    TVariable *constant = new TVariable(
-        this, name, StaticType::Get<EbtInt, precision, EvqConst, 1, 1>(), SymbolType::BuiltIn);
-    TConstantUnion *unionArray = new TConstantUnion[1];
-    unionArray[0].setIConst(value);
-    constant->shareConstPointer(unionArray);
-    return insert(level, constant);
-}
-
-template <TPrecision precision>
-bool TSymbolTable::insertConstIntExt(ESymbolLevel level,
-                                     TExtension ext,
-                                     const ImmutableString &name,
-                                     int value)
-{
-    TVariable *constant = new TVariable(
-        this, name, StaticType::Get<EbtInt, precision, EvqConst, 1, 1>(), SymbolType::BuiltIn, ext);
-    TConstantUnion *unionArray = new TConstantUnion[1];
-    unionArray[0].setIConst(value);
-    constant->shareConstPointer(unionArray);
-    return insert(level, constant);
-}
-
-template <TPrecision precision>
-bool TSymbolTable::insertConstIvec3(ESymbolLevel level,
-                                    const ImmutableString &name,
-                                    const std::array<int, 3> &values)
-{
-    TVariable *constantIvec3 = new TVariable(
-        this, name, StaticType::Get<EbtInt, precision, EvqConst, 3, 1>(), SymbolType::BuiltIn);
-
-    TConstantUnion *unionArray = new TConstantUnion[3];
-    for (size_t index = 0u; index < 3u; ++index)
-    {
-        unionArray[index].setIConst(values[index]);
-    }
-    constantIvec3->shareConstPointer(unionArray);
-
-    return insert(level, constantIvec3);
-}
-
-void TSymbolTable::insertBuiltIn(ESymbolLevel level,
-                                 TOperator op,
-                                 TExtension ext,
-                                 const TType *rvalue,
-                                 const char *name,
-                                 const TType *ptype1,
-                                 const TType *ptype2,
-                                 const TType *ptype3,
-                                 const TType *ptype4,
-                                 const TType *ptype5)
-{
-    if (ptype1->getBasicType() == EbtGSampler2D)
-    {
-        insertUnmangledBuiltIn(name, ext, level);
-        bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
-        insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
-                      StaticType::GetBasic<EbtSampler2D>(), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
-                      StaticType::GetBasic<EbtISampler2D>(), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
-                      StaticType::GetBasic<EbtUSampler2D>(), ptype2, ptype3, ptype4, ptype5);
-    }
-    else if (ptype1->getBasicType() == EbtGSampler3D)
-    {
-        insertUnmangledBuiltIn(name, ext, level);
-        bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
-        insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
-                      StaticType::GetBasic<EbtSampler3D>(), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
-                      StaticType::GetBasic<EbtISampler3D>(), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
-                      StaticType::GetBasic<EbtUSampler3D>(), ptype2, ptype3, ptype4, ptype5);
-    }
-    else if (ptype1->getBasicType() == EbtGSamplerCube)
-    {
-        insertUnmangledBuiltIn(name, ext, level);
-        bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
-        insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
-                      StaticType::GetBasic<EbtSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
-                      StaticType::GetBasic<EbtISamplerCube>(), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
-                      StaticType::GetBasic<EbtUSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
-    }
-    else if (ptype1->getBasicType() == EbtGSampler2DArray)
-    {
-        insertUnmangledBuiltIn(name, ext, level);
-        bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
-        insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
-                      StaticType::GetBasic<EbtSampler2DArray>(), ptype2, ptype3, ptype4,
-                      ptype5);
-        insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
-                      StaticType::GetBasic<EbtISampler2DArray>(), ptype2, ptype3, ptype4,
-                      ptype5);
-        insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
-                      StaticType::GetBasic<EbtUSampler2DArray>(), ptype2, ptype3, ptype4,
-                      ptype5);
-    }
-    else if (ptype1->getBasicType() == EbtGSampler2DMS)
-    {
-        insertUnmangledBuiltIn(name, ext, level);
-        bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
-        insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
-                      StaticType::GetBasic<EbtSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
-                      StaticType::GetBasic<EbtISampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
-                      StaticType::GetBasic<EbtUSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
-    }
-    else if (IsGImage(ptype1->getBasicType()))
-    {
-        insertUnmangledBuiltIn(name, ext, level);
-
-        const TType *floatType    = StaticType::GetBasic<EbtFloat, 4>();
-        const TType *intType      = StaticType::GetBasic<EbtInt, 4>();
-        const TType *unsignedType = StaticType::GetBasic<EbtUInt, 4>();
-
-        const TType *floatImage    = StaticType::GetForFloatImage(ptype1->getBasicType());
-        const TType *intImage      = StaticType::GetForIntImage(ptype1->getBasicType());
-        const TType *unsignedImage = StaticType::GetForUintImage(ptype1->getBasicType());
-
-        // GLSL ES 3.10, Revision 4, 8.12 Image Functions
-        if (rvalue->getBasicType() == EbtGVec4)
-        {
-            // imageLoad
-            insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
-            insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
-            insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
-        }
-        else if (rvalue->getBasicType() == EbtVoid)
-        {
-            // imageStore
-            insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
-            insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
-            insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
-        }
-        else
-        {
-            // imageSize
-            insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
-            insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
-            insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
-        }
-    }
-    else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
-             IsGenType(ptype4))
-    {
-        ASSERT(!ptype5);
-        insertUnmangledBuiltIn(name, ext, level);
-        insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
-                      SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
-        insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
-                      SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
-        insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
-                      SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
-        insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
-                      SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
-    }
-    else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
-    {
-        ASSERT(!ptype4 && !ptype5);
-        insertUnmangledBuiltIn(name, ext, level);
-        insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
-                      VectorType(ptype2, 2), VectorType(ptype3, 2));
-        insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
-                      VectorType(ptype2, 3), VectorType(ptype3, 3));
-        insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
-                      VectorType(ptype2, 4), VectorType(ptype3, 4));
-    }
-    else
-    {
-        size_t paramCount       = 1;
-        TConstParameter *params = new TConstParameter[5];
-        new (params) TConstParameter(ptype1);
-
-        if (ptype2)
-        {
-            new (params + 1) TConstParameter(ptype2);
-            paramCount = 2;
-        }
-        if (ptype3)
-        {
-            new (params + 2) TConstParameter(ptype3);
-            paramCount = 3;
-        }
-        if (ptype4)
-        {
-            new (params + 3) TConstParameter(ptype4);
-            paramCount = 4;
-        }
-        if (ptype5)
-        {
-            new (params + 4) TConstParameter(ptype5);
-            paramCount = 5;
-        }
-        TFunction *function =
-            new TFunction(this, ImmutableString(name), ext, params, paramCount, rvalue, op, false);
-
-        ASSERT(hasUnmangledBuiltInAtLevel(name, level));
-        insert(level, function);
-    }
-}
-
-void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
-                                   TOperator op,
-                                   const TType *rvalue,
-                                   const TType *ptype1,
-                                   const TType *ptype2,
-                                   const TType *ptype3,
-                                   const TType *ptype4,
-                                   const TType *ptype5)
-{
-    const char *name = GetOperatorString(op);
-    ASSERT(strlen(name) > 0);
-    insertUnmangledBuiltIn(name, TExtension::UNDEFINED, level);
-    insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
-                  ptype5);
-}
-
-void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
-                                   TOperator op,
-                                   TExtension ext,
-                                   const TType *rvalue,
-                                   const TType *ptype1,
-                                   const TType *ptype2,
-                                   const TType *ptype3,
-                                   const TType *ptype4,
-                                   const TType *ptype5)
-{
-    const char *name = GetOperatorString(op);
-    insertUnmangledBuiltIn(name, ext, level);
-    insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
-}
-
-void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
-                                                     TOperator op,
-                                                     const TType *rvalue,
-                                                     const char *name)
-{
-    insertUnmangledBuiltIn(name, TExtension::UNDEFINED, level);
-    insert(level, new TFunction(this, ImmutableString(name), TExtension::UNDEFINED, nullptr, 0,
-                                rvalue, op, false));
-}
-
-void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
-                                                        TExtension ext,
-                                                        TOperator op,
-                                                        const TType *rvalue,
-                                                        const char *name)
-{
-    insertUnmangledBuiltIn(name, ext, level);
-    insert(level, new TFunction(this, ImmutableString(name), ext, nullptr, 0, rvalue, op, false));
-}
-
 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
@@ -730,86 +291,38 @@ bool TSymbolTable::isVaryingInvariant(co
 }
 
 void TSymbolTable::setGlobalInvariant(bool invariant)
 {
     ASSERT(atGlobalLevel());
     mTable.back()->setGlobalInvariant(invariant);
 }
 
-void TSymbolTable::insertUnmangledBuiltIn(const char *name, TExtension ext, ESymbolLevel level)
-{
-    ASSERT(level >= 0 && level <= LAST_BUILTIN_LEVEL);
-    ASSERT(mUserDefinedUniqueIdsStart == -1);
-    mBuiltInTable[level]->insertUnmangledBuiltIn(name, ext);
-}
-
-bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
-{
-    ASSERT(level >= 0 && level <= LAST_BUILTIN_LEVEL);
-    return mBuiltInTable[level]->getUnmangledBuiltIn(ImmutableString(name)) != nullptr;
-}
-
-const UnmangledBuiltIn *TSymbolTable::getUnmangledBuiltInForShaderVersion(
-    const ImmutableString &name,
-    int shaderVersion)
-{
-    for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
-    {
-        if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
-        {
-            --level;
-        }
-        if (level == ESSL3_BUILTINS && shaderVersion < 300)
-        {
-            --level;
-        }
-        if (level == ESSL1_BUILTINS && shaderVersion != 100)
-        {
-            --level;
-        }
-
-        const UnmangledBuiltIn *builtIn = mBuiltInTable[level]->getUnmangledBuiltIn(name);
-        if (builtIn != nullptr)
-        {
-            return builtIn;
-        }
-    }
-    return nullptr;
-}
-
-void TSymbolTable::markBuiltInInitializationFinished()
-{
-    mUserDefinedUniqueIdsStart = mUniqueIdCounter;
-}
-
 void TSymbolTable::clearCompilationResults()
 {
-    mUniqueIdCounter = mUserDefinedUniqueIdsStart;
+    mUniqueIdCounter = kLastBuiltInId + 1;
+    mVariableMetadata.clear();
+    mGlInVariableWithArraySize = nullptr;
 
     // User-defined scopes should have already been cleared when the compilation finished.
     ASSERT(mTable.size() == 0u);
 }
 
 int TSymbolTable::nextUniqueIdValue()
 {
     ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
     return ++mUniqueIdCounter;
 }
 
 void TSymbolTable::initializeBuiltIns(sh::GLenum type,
                                       ShShaderSpec spec,
                                       const ShBuiltInResources &resources)
 {
-    ASSERT(isEmpty());
-    pushBuiltInLevel();  // COMMON_BUILTINS
-    pushBuiltInLevel();  // ESSL1_BUILTINS
-    pushBuiltInLevel();  // ESSL3_BUILTINS
-    pushBuiltInLevel();  // ESSL3_1_BUILTINS
-    pushBuiltInLevel();  // GLSL_BUILTINS
+    mShaderType = type;
+    mResources  = resources;
 
     // We need just one precision stack level for predefined precisions.
     mPrecisionStack.push_back(std::unique_ptr<PrecisionStackLevel>(new PrecisionStackLevel));
 
     switch (type)
     {
         case GL_FRAGMENT_SHADER:
             setDefaultPrecision(EbtInt, EbpMedium);
@@ -832,991 +345,23 @@ void TSymbolTable::initializeBuiltIns(sh
     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);
 
     setDefaultPrecision(EbtAtomicCounter, EbpHigh);
 
-    initializeBuiltInFunctions(type);
     initializeBuiltInVariables(type, spec, resources);
-    markBuiltInInitializationFinished();
+    mUniqueIdCounter = kLastBuiltInId + 1;
 }
 
 void TSymbolTable::initSamplerDefaultPrecision(TBasicType samplerType)
 {
-    ASSERT(samplerType > EbtGuardSamplerBegin && samplerType < EbtGuardSamplerEnd);
+    ASSERT(samplerType >= EbtGuardSamplerBegin && samplerType <= EbtGuardSamplerEnd);
     setDefaultPrecision(samplerType, EbpLow);
 }
 
-void TSymbolTable::initializeBuiltInFunctions(sh::GLenum type)
+TSymbolTable::VariableMetadata::VariableMetadata() : staticRead(false), staticWrite(false)
 {
-    const TType *voidType = StaticType::GetBasic<EbtVoid>();
-    const TType *float1   = StaticType::GetBasic<EbtFloat>();
-    const TType *float2   = StaticType::GetBasic<EbtFloat, 2>();
-    const TType *float3   = StaticType::GetBasic<EbtFloat, 3>();
-    const TType *float4   = StaticType::GetBasic<EbtFloat, 4>();
-    const TType *int1     = StaticType::GetBasic<EbtInt>();
-    const TType *int2     = StaticType::GetBasic<EbtInt, 2>();
-    const TType *int3     = StaticType::GetBasic<EbtInt, 3>();
-    const TType *uint1    = StaticType::GetBasic<EbtUInt>();
-    const TType *bool1    = StaticType::GetBasic<EbtBool>();
-    const TType *genType  = StaticType::GetBasic<EbtGenType>();
-    const TType *genIType = StaticType::GetBasic<EbtGenIType>();
-    const TType *genUType = StaticType::GetBasic<EbtGenUType>();
-    const TType *genBType = StaticType::GetBasic<EbtGenBType>();
-
-    //
-    // Angle and Trigonometric Functions.
-    //
-    insertBuiltInOp(COMMON_BUILTINS, EOpRadians, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpDegrees, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpSin, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpCos, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpTan, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpAsin, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpAcos, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpAtan, genType, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpAtan, genType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpSinh, genType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpCosh, genType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpTanh, genType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpAsinh, genType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpAcosh, genType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpAtanh, genType, genType);
-
-    //
-    // Exponential Functions.
-    //
-    insertBuiltInOp(COMMON_BUILTINS, EOpPow, genType, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpExp, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpLog, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpExp2, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpLog2, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpSqrt, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpInversesqrt, genType, genType);
-
-    //
-    // Common Functions.
-    //
-    insertBuiltInOp(COMMON_BUILTINS, EOpAbs, genType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpAbs, genIType, genIType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpSign, genType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpSign, genIType, genIType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpFloor, genType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpTrunc, genType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpRound, genType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpRoundEven, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpCeil, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpFract, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpMod, genType, genType, float1);
-    insertBuiltInOp(COMMON_BUILTINS, EOpMod, genType, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpMin, genType, genType, float1);
-    insertBuiltInOp(COMMON_BUILTINS, EOpMin, genType, genType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genIType, genIType, genIType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genIType, genIType, int1);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genUType, genUType, genUType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genUType, genUType, uint1);
-    insertBuiltInOp(COMMON_BUILTINS, EOpMax, genType, genType, float1);
-    insertBuiltInOp(COMMON_BUILTINS, EOpMax, genType, genType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genIType, genIType, genIType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genIType, genIType, int1);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genUType, genUType, genUType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genUType, genUType, uint1);
-    insertBuiltInOp(COMMON_BUILTINS, EOpClamp, genType, genType, float1, float1);
-    insertBuiltInOp(COMMON_BUILTINS, EOpClamp, genType, genType, genType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genIType, genIType, int1, int1);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genIType, genIType, genIType, genIType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genUType, genUType, uint1, uint1);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genUType, genUType, genUType, genUType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpMix, genType, genType, genType, float1);
-    insertBuiltInOp(COMMON_BUILTINS, EOpMix, genType, genType, genType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpMix, genType, genType, genType, genBType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpStep, genType, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpStep, genType, float1, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpSmoothstep, genType, genType, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpSmoothstep, genType, float1, float1, genType);
-
-    const TType *outGenType  = StaticType::GetQualified<EbtGenType, EvqOut>();
-    const TType *outGenIType = StaticType::GetQualified<EbtGenIType, EvqOut>();
-
-    insertBuiltInOp(ESSL3_BUILTINS, EOpModf, genType, genType, outGenType);
-
-    insertBuiltInOp(ESSL3_BUILTINS, EOpIsnan, genBType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpIsinf, genBType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpFloatBitsToInt, genIType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpFloatBitsToUint, genUType, genType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpIntBitsToFloat, genType, genIType);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpUintBitsToFloat, genType, genUType);
-
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpFrexp, genType, genType, outGenIType);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpLdexp, genType, genType, genIType);
-
-    insertBuiltInOp(ESSL3_BUILTINS, EOpPackSnorm2x16, uint1, float2);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpPackUnorm2x16, uint1, float2);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpPackHalf2x16, uint1, float2);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackSnorm2x16, float2, uint1);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackUnorm2x16, float2, uint1);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackHalf2x16, float2, uint1);
-
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpPackUnorm4x8, uint1, float4);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpPackSnorm4x8, uint1, float4);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpUnpackUnorm4x8, float4, uint1);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpUnpackSnorm4x8, float4, uint1);
-
-    //
-    // Geometric Functions.
-    //
-    insertBuiltInOp(COMMON_BUILTINS, EOpLength, float1, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpDistance, float1, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpDot, float1, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpCross, float3, float3, float3);
-    insertBuiltInOp(COMMON_BUILTINS, EOpNormalize, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpFaceforward, genType, genType, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpReflect, genType, genType, genType);
-    insertBuiltInOp(COMMON_BUILTINS, EOpRefract, genType, genType, genType, float1);
-
-    const TType *mat2   = StaticType::GetBasic<EbtFloat, 2, 2>();
-    const TType *mat3   = StaticType::GetBasic<EbtFloat, 3, 3>();
-    const TType *mat4   = StaticType::GetBasic<EbtFloat, 4, 4>();
-    const TType *mat2x3 = StaticType::GetBasic<EbtFloat, 2, 3>();
-    const TType *mat3x2 = StaticType::GetBasic<EbtFloat, 3, 2>();
-    const TType *mat2x4 = StaticType::GetBasic<EbtFloat, 2, 4>();
-    const TType *mat4x2 = StaticType::GetBasic<EbtFloat, 4, 2>();
-    const TType *mat3x4 = StaticType::GetBasic<EbtFloat, 3, 4>();
-    const TType *mat4x3 = StaticType::GetBasic<EbtFloat, 4, 3>();
-
-    //
-    // Matrix Functions.
-    //
-    insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat2, mat2, mat2);
-    insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat3, mat3, mat3);
-    insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat4, mat4, mat4);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat2x3, mat2x3, mat2x3);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat3x2, mat3x2, mat3x2);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat2x4, mat2x4, mat2x4);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat4x2, mat4x2, mat4x2);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat3x4, mat3x4, mat3x4);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat4x3, mat4x3, mat4x3);
-
-    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat2, float2, float2);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat3, float3, float3);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat4, float4, float4);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat2x3, float3, float2);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat3x2, float2, float3);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat2x4, float4, float2);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat4x2, float2, float4);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat3x4, float4, float3);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat4x3, float3, float4);
-
-    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat2, mat2);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat3, mat3);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat4, mat4);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat2x3, mat3x2);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat3x2, mat2x3);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat2x4, mat4x2);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat4x2, mat2x4);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat3x4, mat4x3);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat4x3, mat3x4);
-
-    insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat2);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat3);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat4);
-
-    insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat2, mat2);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat3, mat3);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat4, mat4);
-
-    const TType *vec  = StaticType::GetBasic<EbtVec>();
-    const TType *ivec = StaticType::GetBasic<EbtIVec>();
-    const TType *uvec = StaticType::GetBasic<EbtUVec>();
-    const TType *bvec = StaticType::GetBasic<EbtBVec>();
-
-    //
-    // Vector relational functions.
-    //
-    insertBuiltInOp(COMMON_BUILTINS, EOpLessThanComponentWise, bvec, vec, vec);
-    insertBuiltInOp(COMMON_BUILTINS, EOpLessThanComponentWise, bvec, ivec, ivec);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpLessThanComponentWise, bvec, uvec, uvec);
-    insertBuiltInOp(COMMON_BUILTINS, EOpLessThanEqualComponentWise, bvec, vec, vec);
-    insertBuiltInOp(COMMON_BUILTINS, EOpLessThanEqualComponentWise, bvec, ivec, ivec);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpLessThanEqualComponentWise, bvec, uvec, uvec);
-    insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanComponentWise, bvec, vec, vec);
-    insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanComponentWise, bvec, ivec, ivec);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpGreaterThanComponentWise, bvec, uvec, uvec);
-    insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanEqualComponentWise, bvec, vec, vec);
-    insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanEqualComponentWise, bvec, ivec, ivec);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpGreaterThanEqualComponentWise, bvec, uvec, uvec);
-    insertBuiltInOp(COMMON_BUILTINS, EOpEqualComponentWise, bvec, vec, vec);
-    insertBuiltInOp(COMMON_BUILTINS, EOpEqualComponentWise, bvec, ivec, ivec);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpEqualComponentWise, bvec, uvec, uvec);
-    insertBuiltInOp(COMMON_BUILTINS, EOpEqualComponentWise, bvec, bvec, bvec);
-    insertBuiltInOp(COMMON_BUILTINS, EOpNotEqualComponentWise, bvec, vec, vec);
-    insertBuiltInOp(COMMON_BUILTINS, EOpNotEqualComponentWise, bvec, ivec, ivec);
-    insertBuiltInOp(ESSL3_BUILTINS, EOpNotEqualComponentWise, bvec, uvec, uvec);
-    insertBuiltInOp(COMMON_BUILTINS, EOpNotEqualComponentWise, bvec, bvec, bvec);
-    insertBuiltInOp(COMMON_BUILTINS, EOpAny, bool1, bvec);
-    insertBuiltInOp(COMMON_BUILTINS, EOpAll, bool1, bvec);
-    insertBuiltInOp(COMMON_BUILTINS, EOpLogicalNotComponentWise, bvec, bvec);
-
-    //
-    // Integer functions
-    //
-    const TType *outGenUType = StaticType::GetQualified<EbtGenUType, EvqOut>();
-
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldExtract, genIType, genIType, int1, int1);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldExtract, genUType, genUType, int1, int1);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldInsert, genIType, genIType, genIType, int1, int1);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldInsert, genUType, genUType, genUType, int1, int1);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldReverse, genIType, genIType);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldReverse, genUType, genUType);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitCount, genIType, genIType);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitCount, genIType, genUType);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindLSB, genIType, genIType);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindLSB, genIType, genUType);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindMSB, genIType, genIType);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindMSB, genIType, genUType);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpUaddCarry, genUType, genUType, genUType, outGenUType);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpUsubBorrow, genUType, genUType, genUType, outGenUType);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpUmulExtended, voidType, genUType, genUType, outGenUType,
-                    outGenUType);
-    insertBuiltInOp(ESSL3_1_BUILTINS, EOpImulExtended, voidType, genIType, genIType, outGenIType,
-                    outGenIType);
-
-    const TType *sampler2D   = StaticType::GetBasic<EbtSampler2D>();
-    const TType *samplerCube = StaticType::GetBasic<EbtSamplerCube>();
-    const TType *samplerExternalOES = StaticType::GetBasic<EbtSamplerExternalOES>();
-
-    //
-    // Texture Functions for GLSL ES 1.0
-    //
-    insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2);
-    insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3);
-    insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4);
-    insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3);
-
-    // These are extension functions from OES_EGL_image_external and
-    // NV_EGL_stream_consumer_external. We don't have a way to mark a built-in with two alternative
-    // extensions, so these are marked with none. This is fine, since these functions overload core
-    // function names and the functions require a samplerExternalOES parameter, which can only be
-    // created if one of the extensions is enabled.
-    // TODO(oetuaho): Consider implementing a cleaner solution.
-    insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", samplerExternalOES, float2);
-    insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, float3);
-    insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, float4);
-
-    // Note that ARB_texture_rectangle extension directive defaults to enabled in case the extension
-    // is supported. The symbols are still conditional on the extension.
-    const TType *sampler2DRect = StaticType::GetBasic<EbtSampler2DRect>();
-    insertBuiltIn(ESSL1_BUILTINS, TExtension::ARB_texture_rectangle, float4, "texture2DRect",
-                  sampler2DRect, float2);
-    insertBuiltIn(ESSL1_BUILTINS, TExtension::ARB_texture_rectangle, float4, "texture2DRectProj",
-                  sampler2DRect, float3);
-    insertBuiltIn(ESSL1_BUILTINS, TExtension::ARB_texture_rectangle, float4, "texture2DRectProj",
-                  sampler2DRect, float4);
-
-    /* The *Grad* variants are new to both vertex and fragment shaders; the fragment
-     * shader specific pieces are added separately below.
-     */
-    insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4, "texture2DGradEXT",
-                  sampler2D, float2, float2, float2);
-    insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
-                  "texture2DProjGradEXT", sampler2D, float3, float2, float2);
-    insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
-                  "texture2DProjGradEXT", sampler2D, float4, float2, float2);
-    insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4, "textureCubeGradEXT",
-                  samplerCube, float3, float3, float3);
-
-    if (type == GL_FRAGMENT_SHADER)
-    {
-        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2, float1);
-        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3, float1);
-        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4, float1);
-        insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3, float1);
-
-        insertBuiltInOp(ESSL1_BUILTINS, EOpDFdx, TExtension::OES_standard_derivatives, genType,
-                        genType);
-        insertBuiltInOp(ESSL1_BUILTINS, EOpDFdy, TExtension::OES_standard_derivatives, genType,
-                        genType);
-        insertBuiltInOp(ESSL1_BUILTINS, EOpFwidth, TExtension::OES_standard_derivatives, genType,
-                        genType);
-
-        insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4, "texture2DLodEXT",
-                      sampler2D, float2, float1);
-        insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
-                      "texture2DProjLodEXT", sampler2D, float3, float1);
-        insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
-                      "texture2DProjLodEXT", sampler2D, float4, float1);
-        insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
-                      "textureCubeLodEXT", samplerCube, float3, float1);
-    }
-
-    if (type == GL_VERTEX_SHADER)
-    {
-        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DLod", sampler2D, float2, float1);
-        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float3, float1);
-        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float4, float1);
-        insertBuiltIn(ESSL1_BUILTINS, float4, "textureCubeLod", samplerCube, float3, float1);
-    }
-
-    const TType *gvec4 = StaticType::GetBasic<EbtGVec4>();
-
-    const TType *gsampler2D      = StaticType::GetBasic<EbtGSampler2D>();
-    const TType *gsamplerCube    = StaticType::GetBasic<EbtGSamplerCube>();
-    const TType *gsampler3D      = StaticType::GetBasic<EbtGSampler3D>();
-    const TType *gsampler2DArray = StaticType::GetBasic<EbtGSampler2DArray>();
-    const TType *gsampler2DMS    = StaticType::GetBasic<EbtGSampler2DMS>();
-
-    //
-    // Texture Functions for GLSL ES 3.0
-    //
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsamplerCube, float3);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2D, float2, float1);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler3D, float3, float1);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsamplerCube, float3, float1);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2DArray, float3, float1);
-
-    insertBuiltIn(ESSL3_BUILTINS, TExtension::OES_EGL_image_external_essl3, float4, "texture",
-                  samplerExternalOES, float2);
-    insertBuiltIn(ESSL3_BUILTINS, TExtension::OES_EGL_image_external_essl3, float4, "textureProj",
-                  samplerExternalOES, float3);
-    insertBuiltIn(ESSL3_BUILTINS, TExtension::OES_EGL_image_external_essl3, float4, "textureProj",
-                  samplerExternalOES, float4);
-
-    const TType *samplerExternal2DY2YEXT = StaticType::GetBasic<EbtSamplerExternal2DY2YEXT>();
-
-    insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texture",
-                  samplerExternal2DY2YEXT, float2);
-    insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj",
-                  samplerExternal2DY2YEXT, float3);
-    insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj",
-                  samplerExternal2DY2YEXT, float4);
-
-    const TType *yuvCscStandardEXT = StaticType::GetBasic<EbtYuvCscStandardEXT>();
-
-    insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float3, "rgb_2_yuv", float3,
-                  yuvCscStandardEXT);
-    insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float3, "yuv_2_rgb", float3,
-                  yuvCscStandardEXT);
-
-    if (type == GL_FRAGMENT_SHADER)
-    {
-        insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2, float1);
-        insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3, float1);
-        insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsamplerCube, float3, float1);
-        insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3, float1);
-        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3, float1);
-        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4, float1);
-        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4, float1);
-
-        insertBuiltIn(ESSL3_BUILTINS, TExtension::OES_EGL_image_external_essl3, float4, "texture",
-                      samplerExternalOES, float2, float1);
-        insertBuiltIn(ESSL3_BUILTINS, TExtension::OES_EGL_image_external_essl3, float4,
-                      "textureProj", samplerExternalOES, float3, float1);
-        insertBuiltIn(ESSL3_BUILTINS, TExtension::OES_EGL_image_external_essl3, float4,
-                      "textureProj", samplerExternalOES, float4, float1);
-
-        insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texture",
-                      samplerExternal2DY2YEXT, float2, float1);
-        insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj",
-                      samplerExternal2DY2YEXT, float3, float1);
-        insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj",
-                      samplerExternal2DY2YEXT, float4, float1);
-    }
-
-    const TType *sampler2DShadow      = StaticType::GetBasic<EbtSampler2DShadow>();
-    const TType *samplerCubeShadow    = StaticType::GetBasic<EbtSamplerCubeShadow>();
-    const TType *sampler2DArrayShadow = StaticType::GetBasic<EbtSampler2DArrayShadow>();
-
-    insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DShadow, float3);
-    insertBuiltIn(ESSL3_BUILTINS, float1, "texture", samplerCubeShadow, float4);
-    insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DArrayShadow, float4);
-    insertBuiltIn(ESSL3_BUILTINS, float1, "textureProj", sampler2DShadow, float4);
-    insertBuiltIn(ESSL3_BUILTINS, float1, "textureLod", sampler2DShadow, float3, float1);
-
-    if (type == GL_FRAGMENT_SHADER)
-    {
-        insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DShadow, float3, float1);
-        insertBuiltIn(ESSL3_BUILTINS, float1, "texture", samplerCubeShadow, float4, float1);
-        insertBuiltIn(ESSL3_BUILTINS, float1, "textureProj", sampler2DShadow, float4, float1);
-    }
-
-    insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsampler2D, int1);
-    insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", gsampler3D, int1);
-    insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsamplerCube, int1);
-    insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", gsampler2DArray, int1);
-    insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", sampler2DShadow, int1);
-    insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerCubeShadow, int1);
-    insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", sampler2DArrayShadow, int1);
-    insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsampler2DMS);
-
-    insertBuiltIn(ESSL3_BUILTINS, TExtension::OES_EGL_image_external_essl3, int2, "textureSize",
-                  samplerExternalOES, int1);
-
-    insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, int2, "textureSize",
-                  samplerExternal2DY2YEXT, int1);
-
-    if (type == GL_FRAGMENT_SHADER)
-    {
-        insertBuiltInOp(ESSL3_BUILTINS, EOpDFdx, genType, genType);
-        insertBuiltInOp(ESSL3_BUILTINS, EOpDFdy, genType, genType);
-        insertBuiltInOp(ESSL3_BUILTINS, EOpFwidth, genType, genType);
-    }
-
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler3D, float3, int3);
-    insertBuiltIn(ESSL3_BUILTINS, float1, "textureOffset", sampler2DShadow, float3, int2);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2DArray, float3, int2);
-
-    if (type == GL_FRAGMENT_SHADER)
-    {
-        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2, float1);
-        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler3D, float3, int3, float1);
-        insertBuiltIn(ESSL3_BUILTINS, float1, "textureOffset", sampler2DShadow, float3, int2,
-                      float1);
-        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2DArray, float3, int2,
-                      float1);
-    }
-
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float3, int2);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float4, int2);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler3D, float4, int3);
-    insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjOffset", sampler2DShadow, float4, int2);
-
-    if (type == GL_FRAGMENT_SHADER)
-    {
-        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float3, int2, float1);
-        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float4, int2, float1);
-        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler3D, float4, int3, float1);
-        insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjOffset", sampler2DShadow, float4, int2,
-                      float1);
-    }
-
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler2D, float2, float1, int2);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler3D, float3, float1, int3);
-    insertBuiltIn(ESSL3_BUILTINS, float1, "textureLodOffset", sampler2DShadow, float3, float1,
-                  int2);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler2DArray, float3, float1, int2);
-
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler2D, float3, float1);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler2D, float4, float1);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler3D, float4, float1);
-    insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjLod", sampler2DShadow, float4, float1);
-
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler2D, float3, float1, int2);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler2D, float4, float1, int2);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler3D, float4, float1, int3);
-    insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjLodOffset", sampler2DShadow, float4, float1,
-                  int2);
-
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2D, int2, int1);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler3D, int3, int1);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2DArray, int3, int1);
-
-    insertBuiltIn(ESSL3_BUILTINS, TExtension::OES_EGL_image_external_essl3, float4, "texelFetch",
-                  samplerExternalOES, int2, int1);
-
-    insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texelFetch",
-                  samplerExternal2DY2YEXT, int2, int1);
-
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2D, int2, int1, int2);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler3D, int3, int1, int3);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2DArray, int3, int1, int2);
-
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler2D, float2, float2, float2);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler3D, float3, float3, float3);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsamplerCube, float3, float3, float3);
-    insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", sampler2DShadow, float3, float2, float2);
-    insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", samplerCubeShadow, float4, float3, float3);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler2DArray, float3, float2, float2);
-    insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", sampler2DArrayShadow, float4, float2,
-                  float2);
-
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler2D, float2, float2, float2,
-                  int2);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler3D, float3, float3, float3,
-                  int3);
-    insertBuiltIn(ESSL3_BUILTINS, float1, "textureGradOffset", sampler2DShadow, float3, float2,
-                  float2, int2);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler2DArray, float3, float2,
-                  float2, int2);
-    insertBuiltIn(ESSL3_BUILTINS, float1, "textureGradOffset", sampler2DArrayShadow, float4, float2,
-                  float2, int2);
-
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler2D, float3, float2, float2);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler2D, float4, float2, float2);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler3D, float4, float3, float3);
-    insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGrad", sampler2DShadow, float4, float2,
-                  float2);
-
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler2D, float3, float2,
-                  float2, int2);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler2D, float4, float2,
-                  float2, int2);
-    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler3D, float4, float3,
-                  float3, int3);
-    insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGradOffset", sampler2DShadow, float4, float2,
-                  float2, int2);
-
-    const TType *atomicCounter = StaticType::GetBasic<EbtAtomicCounter>();
-    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounter", atomicCounter);
-    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounterIncrement", atomicCounter);
-    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounterDecrement", atomicCounter);
-
-    // Insert all atomic memory functions
-    const TType *int1InOut  = StaticType::GetQualified<EbtInt, EvqInOut>();
-    const TType *uint1InOut = StaticType::GetQualified<EbtUInt, EvqInOut>();
-    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicAdd", uint1InOut, uint1);
-    insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicAdd", int1InOut, int1);
-    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicMin", uint1InOut, uint1);
-    insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicMin", int1InOut, int1);
-    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicMax", uint1InOut, uint1);
-    insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicMax", int1InOut, int1);
-    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicAnd", uint1InOut, uint1);
-    insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicAnd", int1InOut, int1);
-    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicOr", uint1InOut, uint1);
-    insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicOr", int1InOut, int1);
-    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicXor", uint1InOut, uint1);
-    insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicXor", int1InOut, int1);
-    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicExchange", uint1InOut, uint1);
-    insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicExchange", int1InOut, int1);
-    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCompSwap", uint1InOut, uint1, uint1);
-    insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicCompSwap", int1InOut, int1, int1);
-
-    const TType *gimage2D      = StaticType::GetBasic<EbtGImage2D>();
-    const TType *gimage3D      = StaticType::GetBasic<EbtGImage3D>();
-    const TType *gimage2DArray = StaticType::GetBasic<EbtGImage2DArray>();
-    const TType *gimageCube    = StaticType::GetBasic<EbtGImageCube>();
-
-    insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage2D, int2, gvec4);
-    insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage3D, int3, gvec4);
-    insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage2DArray, int3, gvec4);
-    insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimageCube, int3, gvec4);
-
-    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage2D, int2);
-    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage3D, int3);
-    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage2DArray, int3);
-    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimageCube, int3);
-
-    insertBuiltIn(ESSL3_1_BUILTINS, int2, "imageSize", gimage2D);
-    insertBuiltIn(ESSL3_1_BUILTINS, int3, "imageSize", gimage3D);
-    insertBuiltIn(ESSL3_1_BUILTINS, int3, "imageSize", gimage2DArray);
-    insertBuiltIn(ESSL3_1_BUILTINS, int2, "imageSize", gimageCube);
-
-    insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrier, voidType,
-                                      "memoryBarrier");
-    insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierAtomicCounter, voidType,
-                                      "memoryBarrierAtomicCounter");
-    insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierBuffer, voidType,
-                                      "memoryBarrierBuffer");
-    insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierImage, voidType,
-                                      "memoryBarrierImage");
-
-    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "texelFetch", gsampler2DMS, int2, int1);
-
-    // Insert all variations of textureGather.
-    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2D, float2);
-    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2D, float2, int1);
-    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2DArray, float3);
-    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2DArray, float3, int1);
-    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsamplerCube, float3);
-    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsamplerCube, float3, int1);
-    insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DShadow, float2);
-    insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DShadow, float2, float1);
-    insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DArrayShadow, float3);
-    insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DArrayShadow, float3, float1);
-    insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", samplerCubeShadow, float3);
-    insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", samplerCubeShadow, float3, float1);
-
-    // Insert all variations of textureGatherOffset.
-    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2D, float2, int2);
-    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2D, float2, int2, int1);
-    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2DArray, float3, int2);
-    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2DArray, float3, int2,
-                  int1);
-    insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGatherOffset", sampler2DShadow, float2, float1,
-                  int2);
-    insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGatherOffset", sampler2DArrayShadow, float3,
-                  float1, int2);
-
-    if (type == GL_COMPUTE_SHADER)
-    {
-        insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpBarrier, voidType, "barrier");
-        insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierShared, voidType,
-                                          "memoryBarrierShared");
-        insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpGroupMemoryBarrier, voidType,
-                                          "groupMemoryBarrier");
-    }
-
-    if (type == GL_GEOMETRY_SHADER_EXT)
-    {
-        TExtension extension = TExtension::EXT_geometry_shader;
-        insertBuiltInFunctionNoParametersExt(ESSL3_1_BUILTINS, extension, EOpEmitVertex, voidType,
-                                             "EmitVertex");
-        insertBuiltInFunctionNoParametersExt(ESSL3_1_BUILTINS, extension, EOpEndPrimitive, voidType,
-                                             "EndPrimitive");
-    }
-}
-
-void TSymbolTable::initializeBuiltInVariables(sh::GLenum type,
-                                              ShShaderSpec spec,
-                                              const ShBuiltInResources &resources)
-{
-    const TSourceLoc zeroSourceLoc = {0, 0, 0, 0};
-
-    //
-    // Depth range in window coordinates
-    //
-    TFieldList *fields = new TFieldList();
-    auto highpFloat1   = new TType(EbtFloat, EbpHigh, EvqGlobal, 1);
-    TField *near       = new TField(highpFloat1, ImmutableString("near"), zeroSourceLoc);
-    TField *far        = new TField(highpFloat1, ImmutableString("far"), zeroSourceLoc);
-    TField *diff       = new TField(highpFloat1, ImmutableString("diff"), zeroSourceLoc);
-    fields->push_back(near);
-    fields->push_back(far);
-    fields->push_back(diff);
-    TStructure *depthRangeStruct = new TStructure(this, ImmutableString("gl_DepthRangeParameters"),
-                                                  fields, SymbolType::BuiltIn);
-    insertStructType(COMMON_BUILTINS, depthRangeStruct);
-    TType *depthRangeType = new TType(depthRangeStruct);
-    depthRangeType->setQualifier(EvqUniform);
-    depthRangeType->realize();
-    insertVariable(COMMON_BUILTINS, ImmutableString("gl_DepthRange"), depthRangeType);
-
-    //
-    // Implementation dependent built-in constants.
-    //
-    insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxVertexAttribs"),
-                              resources.MaxVertexAttribs);
-    insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxVertexUniformVectors"),
-                              resources.MaxVertexUniformVectors);
-    insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxVertexTextureImageUnits"),
-                              resources.MaxVertexTextureImageUnits);
-    insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxCombinedTextureImageUnits"),
-                              resources.MaxCombinedTextureImageUnits);
-    insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxTextureImageUnits"),
-                              resources.MaxTextureImageUnits);
-    insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxFragmentUniformVectors"),
-                              resources.MaxFragmentUniformVectors);
-
-    insertConstInt<EbpMedium>(ESSL1_BUILTINS, ImmutableString("gl_MaxVaryingVectors"),
-                              resources.MaxVaryingVectors);
-
-    insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxDrawBuffers"),
-                              resources.MaxDrawBuffers);
-    insertConstIntExt<EbpMedium>(COMMON_BUILTINS, TExtension::EXT_blend_func_extended,
-                                 ImmutableString("gl_MaxDualSourceDrawBuffersEXT"),
-                                 resources.MaxDualSourceDrawBuffers);
-
-    insertConstInt<EbpMedium>(ESSL3_BUILTINS, ImmutableString("gl_MaxVertexOutputVectors"),
-                              resources.MaxVertexOutputVectors);
-    insertConstInt<EbpMedium>(ESSL3_BUILTINS, ImmutableString("gl_MaxFragmentInputVectors"),
-                              resources.MaxFragmentInputVectors);
-    insertConstInt<EbpMedium>(ESSL3_BUILTINS, ImmutableString("gl_MinProgramTexelOffset"),
-                              resources.MinProgramTexelOffset);
-    insertConstInt<EbpMedium>(ESSL3_BUILTINS, ImmutableString("gl_MaxProgramTexelOffset"),
-                              resources.MaxProgramTexelOffset);
-
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxImageUnits"),
-                              resources.MaxImageUnits);
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxVertexImageUniforms"),
-                              resources.MaxVertexImageUniforms);
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxFragmentImageUniforms"),
-                              resources.MaxFragmentImageUniforms);
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxComputeImageUniforms"),
-                              resources.MaxComputeImageUniforms);
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxCombinedImageUniforms"),
-                              resources.MaxCombinedImageUniforms);
-
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                              ImmutableString("gl_MaxCombinedShaderOutputResources"),
-                              resources.MaxCombinedShaderOutputResources);
-
-    insertConstIvec3<EbpHigh>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxComputeWorkGroupCount"),
-                              resources.MaxComputeWorkGroupCount);
-    insertConstIvec3<EbpHigh>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxComputeWorkGroupSize"),
-                              resources.MaxComputeWorkGroupSize);
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxComputeUniformComponents"),
-                              resources.MaxComputeUniformComponents);
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxComputeTextureImageUnits"),
-                              resources.MaxComputeTextureImageUnits);
-
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxComputeAtomicCounters"),
-                              resources.MaxComputeAtomicCounters);
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                              ImmutableString("gl_MaxComputeAtomicCounterBuffers"),
-                              resources.MaxComputeAtomicCounterBuffers);
-
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxVertexAtomicCounters"),
-                              resources.MaxVertexAtomicCounters);
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxFragmentAtomicCounters"),
-                              resources.MaxFragmentAtomicCounters);
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxCombinedAtomicCounters"),
-                              resources.MaxCombinedAtomicCounters);
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxAtomicCounterBindings"),
-                              resources.MaxAtomicCounterBindings);
-
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxVertexAtomicCounterBuffers"),
-                              resources.MaxVertexAtomicCounterBuffers);
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                              ImmutableString("gl_MaxFragmentAtomicCounterBuffers"),
-                              resources.MaxFragmentAtomicCounterBuffers);
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                              ImmutableString("gl_MaxCombinedAtomicCounterBuffers"),
-                              resources.MaxCombinedAtomicCounterBuffers);
-    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxAtomicCounterBufferSize"),
-                              resources.MaxAtomicCounterBufferSize);
-
-    {
-        TExtension ext = TExtension::EXT_geometry_shader;
-        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
-                                     ImmutableString("gl_MaxGeometryInputComponents"),
-                                     resources.MaxGeometryInputComponents);
-        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
-                                     ImmutableString("gl_MaxGeometryOutputComponents"),
-                                     resources.MaxGeometryOutputComponents);
-        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
-                                     ImmutableString("gl_MaxGeometryImageUniforms"),
-                                     resources.MaxGeometryImageUniforms);
-        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
-                                     ImmutableString("gl_MaxGeometryTextureImageUnits"),
-                                     resources.MaxGeometryTextureImageUnits);
-        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
-                                     ImmutableString("gl_MaxGeometryOutputVertices"),
-                                     resources.MaxGeometryOutputVertices);
-        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
-                                     ImmutableString("gl_MaxGeometryTotalOutputComponents"),
-                                     resources.MaxGeometryTotalOutputComponents);
-        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
-                                     ImmutableString("gl_MaxGeometryUniformComponents"),
-                                     resources.MaxGeometryUniformComponents);
-        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
-                                     ImmutableString("gl_MaxGeometryAtomicCounters"),
-                                     resources.MaxGeometryAtomicCounters);
-        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
-                                     ImmutableString("gl_MaxGeometryAtomicCounterBuffers"),
-                                     resources.MaxGeometryAtomicCounterBuffers);
-    }
-
-    //
-    // Insert some special built-in variables that are not in
-    // the built-in header files.
-    //
-
-    if (resources.OVR_multiview && type != GL_COMPUTE_SHADER)
-    {
-        const TType *viewIDType = StaticType::Get<EbtUInt, EbpHigh, EvqViewIDOVR, 1, 1>();
-        insertVariableExt(ESSL3_BUILTINS, TExtension::OVR_multiview,
-                          ImmutableString("gl_ViewID_OVR"), viewIDType);
-
-        // ESSL 1.00 doesn't have unsigned integers, so gl_ViewID_OVR is a signed integer in ESSL
-        // 1.00. This is specified in the WEBGL_multiview spec.
-        const TType *viewIDIntType = StaticType::Get<EbtInt, EbpHigh, EvqViewIDOVR, 1, 1>();
-        insertVariableExt(ESSL1_BUILTINS, TExtension::OVR_multiview,
-                          ImmutableString("gl_ViewID_OVR"), viewIDIntType);
-    }
-
-    const TType *positionType    = StaticType::Get<EbtFloat, EbpHigh, EvqPosition, 4, 1>();
-    const TType *primitiveIDType = StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>();
-    const TType *layerType       = StaticType::Get<EbtInt, EbpHigh, EvqLayer, 1, 1>();
-
-    switch (type)
-    {
-        case GL_FRAGMENT_SHADER:
-        {
-            const TType *fragCoordType = StaticType::Get<EbtFloat, EbpMedium, EvqFragCoord, 4, 1>();
-            insertVariable(COMMON_BUILTINS, ImmutableString("gl_FragCoord"), fragCoordType);
-            const TType *frontFacingType = StaticType::GetQualified<EbtBool, EvqFrontFacing>();
-            insertVariable(COMMON_BUILTINS, ImmutableString("gl_FrontFacing"), frontFacingType);
-            const TType *pointCoordType =
-                StaticType::Get<EbtFloat, EbpMedium, EvqPointCoord, 2, 1>();
-            insertVariable(COMMON_BUILTINS, ImmutableString("gl_PointCoord"), pointCoordType);
-
-            const TType *fragColorType = StaticType::Get<EbtFloat, EbpMedium, EvqFragColor, 4, 1>();
-            insertVariable(ESSL1_BUILTINS, ImmutableString("gl_FragColor"), fragColorType);
-
-            TType *fragDataType = new TType(EbtFloat, EbpMedium, EvqFragData, 4);
-            if (spec != SH_WEBGL2_SPEC && spec != SH_WEBGL3_SPEC)
-            {
-                fragDataType->makeArray(resources.MaxDrawBuffers);
-            }
-            else
-            {
-                fragDataType->makeArray(1u);
-            }
-            fragDataType->realize();
-            insertVariable(ESSL1_BUILTINS, ImmutableString("gl_FragData"), fragDataType);
-
-            if (resources.EXT_blend_func_extended)
-            {
-                const TType *secondaryFragColorType =
-                    StaticType::Get<EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4, 1>();
-                insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_blend_func_extended,
-                                  ImmutableString("gl_SecondaryFragColorEXT"),
-                                  secondaryFragColorType);
-                TType *secondaryFragDataType =
-                    new TType(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1);
-                secondaryFragDataType->makeArray(resources.MaxDualSourceDrawBuffers);
-                secondaryFragDataType->realize();
-                insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_blend_func_extended,
-                                  ImmutableString("gl_SecondaryFragDataEXT"),
-                                  secondaryFragDataType);
-            }
-
-            if (resources.EXT_frag_depth)
-            {
-                TType *fragDepthEXTType =
-                    new TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium,
-                              EvqFragDepthEXT, 1);
-                fragDepthEXTType->realize();
-                insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_frag_depth,
-                                  ImmutableString("gl_FragDepthEXT"), fragDepthEXTType);
-            }
-
-            const TType *fragDepthType = StaticType::Get<EbtFloat, EbpHigh, EvqFragDepth, 1, 1>();
-            insertVariable(ESSL3_BUILTINS, ImmutableString("gl_FragDepth"), fragDepthType);
-
-            const TType *lastFragColorType =
-                StaticType::Get<EbtFloat, EbpMedium, EvqLastFragColor, 4, 1>();
-
-            if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch)
-            {
-                TType *lastFragDataType = new TType(EbtFloat, EbpMedium, EvqLastFragData, 4, 1);
-                lastFragDataType->makeArray(resources.MaxDrawBuffers);
-                lastFragDataType->realize();
-
-                if (resources.EXT_shader_framebuffer_fetch)
-                {
-                    insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_shader_framebuffer_fetch,
-                                      ImmutableString("gl_LastFragData"), lastFragDataType);
-                }
-                else if (resources.NV_shader_framebuffer_fetch)
-                {
-                    insertVariableExt(ESSL1_BUILTINS, TExtension::NV_shader_framebuffer_fetch,
-                                      ImmutableString("gl_LastFragColor"), lastFragColorType);
-                    insertVariableExt(ESSL1_BUILTINS, TExtension::NV_shader_framebuffer_fetch,
-                                      ImmutableString("gl_LastFragData"), lastFragDataType);
-                }
-            }
-            else if (resources.ARM_shader_framebuffer_fetch)
-            {
-                insertVariableExt(ESSL1_BUILTINS, TExtension::ARM_shader_framebuffer_fetch,
-                                  ImmutableString("gl_LastFragColorARM"), lastFragColorType);
-            }
-
-            if (resources.EXT_geometry_shader)
-            {
-                TExtension extension = TExtension::EXT_geometry_shader;
-                insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_PrimitiveID"),
-                                  primitiveIDType);
-                insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_Layer"),
-                                  layerType);
-            }
-
-            break;
-        }
-        case GL_VERTEX_SHADER:
-        {
-            insertVariable(COMMON_BUILTINS, ImmutableString("gl_Position"), positionType);
-            const TType *pointSizeType = StaticType::Get<EbtFloat, EbpMedium, EvqPointSize, 1, 1>();
-            insertVariable(COMMON_BUILTINS, ImmutableString("gl_PointSize"), pointSizeType);
-            const TType *instanceIDType = StaticType::Get<EbtInt, EbpHigh, EvqInstanceID, 1, 1>();
-            insertVariable(ESSL3_BUILTINS, ImmutableString("gl_InstanceID"), instanceIDType);
-            const TType *vertexIDType = StaticType::Get<EbtInt, EbpHigh, EvqVertexID, 1, 1>();
-            insertVariable(ESSL3_BUILTINS, ImmutableString("gl_VertexID"), vertexIDType);
-
-            // For internal use by ANGLE - not exposed to the parser.
-            const TType *viewportIndexType =
-                StaticType::Get<EbtInt, EbpHigh, EvqViewportIndex, 1, 1>();
-            insertVariable(GLSL_BUILTINS, ImmutableString("gl_ViewportIndex"), viewportIndexType);
-            // gl_Layer exists in other shader stages in ESSL, but not in vertex shader so far.
-            insertVariable(GLSL_BUILTINS, ImmutableString("gl_Layer"), layerType);
-            break;
-        }
-        case GL_COMPUTE_SHADER:
-        {
-            const TType *numWorkGroupsType =
-                StaticType::Get<EbtUInt, EbpUndefined, EvqNumWorkGroups, 3, 1>();
-            insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_NumWorkGroups"),
-                           numWorkGroupsType);
-            const TType *workGroupSizeType =
-                StaticType::Get<EbtUInt, EbpUndefined, EvqWorkGroupSize, 3, 1>();
-            insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_WorkGroupSize"),
-                           workGroupSizeType);
-            const TType *workGroupIDType =
-                StaticType::Get<EbtUInt, EbpUndefined, EvqWorkGroupID, 3, 1>();
-            insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_WorkGroupID"), workGroupIDType);
-            const TType *localInvocationIDType =
-                StaticType::Get<EbtUInt, EbpUndefined, EvqLocalInvocationID, 3, 1>();
-            insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_LocalInvocationID"),
-                           localInvocationIDType);
-            const TType *globalInvocationIDType =
-                StaticType::Get<EbtUInt, EbpUndefined, EvqGlobalInvocationID, 3, 1>();
-            insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_GlobalInvocationID"),
-                           globalInvocationIDType);
-            const TType *localInvocationIndexType =
-                StaticType::Get<EbtUInt, EbpUndefined, EvqLocalInvocationIndex, 1, 1>();
-            insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_LocalInvocationIndex"),
-                           localInvocationIndexType);
-            break;
-        }
-
-        case GL_GEOMETRY_SHADER_EXT:
-        {
-            TExtension extension = TExtension::EXT_geometry_shader;
-
-            // Add built-in interface block gl_PerVertex and the built-in array gl_in.
-            // TODO(jiawei.shao@intel.com): implement GL_EXT_geometry_point_size.
-            TFieldList *glPerVertexFieldList = new TFieldList();
-            TField *glPositionField =
-                new TField(new TType(*positionType), ImmutableString("gl_Position"), zeroSourceLoc);
-            glPerVertexFieldList->push_back(glPositionField);
-
-            const ImmutableString glPerVertexString("gl_PerVertex");
-            TInterfaceBlock *glPerVertexInBlock =
-                new TInterfaceBlock(this, glPerVertexString, glPerVertexFieldList,
-                                    TLayoutQualifier::Create(), SymbolType::BuiltIn, extension);
-            insertInterfaceBlock(ESSL3_1_BUILTINS, glPerVertexInBlock);
-
-            // The array size of gl_in is undefined until we get a valid input primitive
-            // declaration.
-            TType *glInType =
-                new TType(glPerVertexInBlock, EvqPerVertexIn, TLayoutQualifier::Create());
-            glInType->makeArray(0u);
-            glInType->realize();
-            insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_in"), glInType);
-
-            TInterfaceBlock *glPerVertexOutBlock =
-                new TInterfaceBlock(this, glPerVertexString, glPerVertexFieldList,
-                                    TLayoutQualifier::Create(), SymbolType::BuiltIn);
-            TType *glPositionInBlockType = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
-            glPositionInBlockType->setInterfaceBlock(glPerVertexOutBlock);
-            glPositionInBlockType->realize();
-            insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_Position"),
-                              glPositionInBlockType);
-
-            const TType *primitiveIDInType =
-                StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveIDIn, 1, 1>();
-            insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_PrimitiveIDIn"),
-                              primitiveIDInType);
-            const TType *invocationIDType =
-                StaticType::Get<EbtInt, EbpHigh, EvqInvocationID, 1, 1>();
-            insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_InvocationID"),
-                              invocationIDType);
-            insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_PrimitiveID"),
-                              primitiveIDType);
-            insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_Layer"), layerType);
-
-            break;
-        }
-        default:
-            UNREACHABLE();
-    }
 }
 
 }  // namespace sh
--- a/gfx/angle/checkout/src/compiler/translator/SymbolTable.h
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolTable.h
@@ -25,99 +25,97 @@
 // * 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 <array>
 #include <memory>
 
 #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"
 
 namespace sh
 {
 
-// Define ESymbolLevel as int rather than an enum since level can go
-// above GLOBAL_LEVEL and cause atBuiltInLevel() to fail if the
-// compiler optimizes the >= of the last element to ==.
+// Define ESymbolLevel as int rather than an enum so that we can do arithmetic on it.
 typedef int ESymbolLevel;
 const int COMMON_BUILTINS    = 0;
 const int ESSL1_BUILTINS     = 1;
 const int ESSL3_BUILTINS     = 2;
 const int ESSL3_1_BUILTINS   = 3;
 // GLSL_BUILTINS are desktop GLSL builtins that don't exist in ESSL but are used to implement
 // features in ANGLE's GLSL backend. They're not visible to the parser.
 const int GLSL_BUILTINS      = 4;
 const int LAST_BUILTIN_LEVEL = GLSL_BUILTINS;
-const int GLOBAL_LEVEL       = 5;
 
 struct UnmangledBuiltIn
 {
-    constexpr UnmangledBuiltIn() : extension(TExtension::UNDEFINED) {}
-
     constexpr UnmangledBuiltIn(TExtension extension) : extension(extension) {}
 
     TExtension extension;
 };
 
-class TSymbolTable : angle::NonCopyable
+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();
 
-    // When the symbol table is initialized with the built-ins, there should
-    // 'push' calls, so that built-ins are at level 0 and the shader
-    // globals are at level 1.
-    bool isEmpty() const { return mTable.empty(); }
-    bool atBuiltInLevel() const { return currentLevel() <= LAST_BUILTIN_LEVEL; }
-    bool atGlobalLevel() const { return currentLevel() == GLOBAL_LEVEL; }
+    bool isEmpty() const;
+    bool atGlobalLevel() const;
 
     void push();
     void pop();
 
-    // The declare* entry points are used when parsing and declare symbols at the current scope.
-    // They return the created true in case the declaration was successful, and false if the
-    // declaration failed due to redefinition.
-    bool declareVariable(TVariable *variable);
-    bool declareStructType(TStructure *str);
-    bool declareInterfaceBlock(TInterfaceBlock *interfaceBlock);
+    // 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);
+
     // 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 TFunction *setFunctionParameterNamesFromDefinition(const TFunction *function,
                                                              bool *wasDefinedOut);
 
+    // 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 *findGlobal(const ImmutableString &name) const;
 
     const TSymbol *findBuiltIn(const ImmutableString &name, int shaderVersion) const;
 
-    const TSymbol *findBuiltIn(const ImmutableString &name,
-                               int shaderVersion,
-                               bool includeGLSLBuiltins) 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;".
@@ -141,158 +139,50 @@ class TSymbolTable : angle::NonCopyable
                             ShShaderSpec spec,
                             const ShBuiltInResources &resources);
     void clearCompilationResults();
 
   private:
     friend class TSymbolUniqueId;
     int nextUniqueIdValue();
 
-    class TSymbolTableBuiltInLevel;
     class TSymbolTableLevel;
 
-    void pushBuiltInLevel();
-
-    ESymbolLevel currentLevel() const
-    {
-        return static_cast<ESymbolLevel>(mTable.size() + LAST_BUILTIN_LEVEL);
-    }
-
-    // The insert* entry points are used when initializing the symbol table with built-ins.
-    // They return the created symbol / true in case the declaration was successful, and nullptr /
-    // false if the declaration failed due to redefinition.
-    TVariable *insertVariable(ESymbolLevel level, const ImmutableString &name, const TType *type);
-    void insertVariableExt(ESymbolLevel level,
-                           TExtension ext,
-                           const ImmutableString &name,
-                           const TType *type);
-    bool insertVariable(ESymbolLevel level, TVariable *variable);
-    bool insertStructType(ESymbolLevel level, TStructure *str);
-    bool insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock);
-
-    template <TPrecision precision>
-    bool insertConstInt(ESymbolLevel level, const ImmutableString &name, int value);
-
-    template <TPrecision precision>
-    bool insertConstIntExt(ESymbolLevel level,
-                           TExtension ext,
-                           const ImmutableString &name,
-                           int value);
-
-    template <TPrecision precision>
-    bool insertConstIvec3(ESymbolLevel level,
-                          const ImmutableString &name,
-                          const std::array<int, 3> &values);
-
-    // Note that for inserted built-in functions the const char *name needs to remain valid for the
-    // lifetime of the SymbolTable. SymbolTable does not allocate a copy of it.
-    void insertBuiltIn(ESymbolLevel level,
-                       TOperator op,
-                       TExtension ext,
-                       const TType *rvalue,
-                       const char *name,
-                       const TType *ptype1,
-                       const TType *ptype2 = 0,
-                       const TType *ptype3 = 0,
-                       const TType *ptype4 = 0,
-                       const TType *ptype5 = 0);
-
-    void insertBuiltIn(ESymbolLevel level,
-                       const TType *rvalue,
-                       const char *name,
-                       const TType *ptype1,
-                       const TType *ptype2 = 0,
-                       const TType *ptype3 = 0,
-                       const TType *ptype4 = 0,
-                       const TType *ptype5 = 0)
-    {
-        insertUnmangledBuiltIn(name, TExtension::UNDEFINED, level);
-        insertBuiltIn(level, EOpCallBuiltInFunction, TExtension::UNDEFINED, rvalue, name, ptype1,
-                      ptype2, ptype3, ptype4, ptype5);
-    }
-
-    void insertBuiltIn(ESymbolLevel level,
-                       TExtension ext,
-                       const TType *rvalue,
-                       const char *name,
-                       const TType *ptype1,
-                       const TType *ptype2 = 0,
-                       const TType *ptype3 = 0,
-                       const TType *ptype4 = 0,
-                       const TType *ptype5 = 0)
-    {
-        insertUnmangledBuiltIn(name, ext, level);
-        insertBuiltIn(level, EOpCallBuiltInFunction, ext, rvalue, name, ptype1, ptype2, ptype3,
-                      ptype4, ptype5);
-    }
-
-    void insertBuiltInOp(ESymbolLevel level,
-                         TOperator op,
-                         const TType *rvalue,
-                         const TType *ptype1,
-                         const TType *ptype2 = 0,
-                         const TType *ptype3 = 0,
-                         const TType *ptype4 = 0,
-                         const TType *ptype5 = 0);
-
-    void insertBuiltInOp(ESymbolLevel level,
-                         TOperator op,
-                         TExtension ext,
-                         const TType *rvalue,
-                         const TType *ptype1,
-                         const TType *ptype2 = 0,
-                         const TType *ptype3 = 0,
-                         const TType *ptype4 = 0,
-                         const TType *ptype5 = 0);
-
-    void insertBuiltInFunctionNoParameters(ESymbolLevel level,
-                                           TOperator op,
-                                           const TType *rvalue,
-                                           const char *name);
-
-    void insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
-                                              TExtension ext,
-                                              TOperator op,
-                                              const TType *rvalue,
-                                              const char *name);
-
-    TVariable *insertVariable(ESymbolLevel level,
-                              const ImmutableString &name,
-                              const TType *type,
-                              SymbolType symbolType);
-
-    bool insert(ESymbolLevel level, TSymbol *symbol);
-
     TFunction *findUserDefinedFunction(const ImmutableString &name) const;
 
-    // Used to insert unmangled functions to check redeclaration of built-ins in ESSL 3.00 and
-    // above.
-    void insertUnmangledBuiltIn(const char *name, TExtension ext, ESymbolLevel level);
-
-    bool hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level);
-
     void initSamplerDefaultPrecision(TBasicType samplerType);
 
-    void initializeBuiltInFunctions(sh::GLenum type);
-    void initializeBuiltInVariables(sh::GLenum type,
+    void initializeBuiltInVariables(sh::GLenum shaderType,
                                     ShShaderSpec spec,
                                     const ShBuiltInResources &resources);
-    void markBuiltInInitializationFinished();
 
-    std::vector<std::unique_ptr<TSymbolTableBuiltInLevel>> mBuiltInTable;
     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;
 
     int mUniqueIdCounter;
 
-    // -1 before built-in init has finished, one past the last built-in id afterwards.
-    // TODO(oetuaho): Make this a compile-time constant once the symbol table is initialized at
-    // compile time. http://anglebug.com/1432
-    int mUserDefinedUniqueIdsStart;
+    static const int kLastBuiltInId;
+
+    sh::GLenum mShaderType;
+    ShBuiltInResources mResources;
+
+    struct VariableMetadata
+    {
+        VariableMetadata();
+        bool staticRead;
+        bool staticWrite;
+    };
+
+    // 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_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolTable_autogen.cpp
@@ -0,0 +1,20440 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_builtin_symbols.py using data from builtin_variables.json and
+// builtin_function_declarations.txt.
+//
+// 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.
+//
+// SymbolTable_autogen.cpp:
+//   Compile-time initialized built-ins.
+
+#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_autogen.h"
+
+namespace sh
+{
+
+// Since some of the BuiltInId declarations are used outside of constexpr expressions, we need to
+// have these definitions without an initializer. C++17 should eventually remove the need for this.
+constexpr const TSymbolUniqueId BuiltInId::radians_Float1;
+constexpr const TSymbolUniqueId BuiltInId::radians_Float2;
+constexpr const TSymbolUniqueId BuiltInId::radians_Float3;
+constexpr const TSymbolUniqueId BuiltInId::radians_Float4;
+constexpr const TSymbolUniqueId BuiltInId::degrees_Float1;
+constexpr const TSymbolUniqueId BuiltInId::degrees_Float2;
+constexpr const TSymbolUniqueId BuiltInId::degrees_Float3;
+constexpr const TSymbolUniqueId BuiltInId::degrees_Float4;
+constexpr const TSymbolUniqueId BuiltInId::sin_Float1;
+constexpr const TSymbolUniqueId BuiltInId::sin_Float2;
+constexpr const TSymbolUniqueId BuiltInId::sin_Float3;
+constexpr const TSymbolUniqueId BuiltInId::sin_Float4;
+constexpr const TSymbolUniqueId BuiltInId::cos_Float1;
+constexpr const TSymbolUniqueId BuiltInId::cos_Float2;
+constexpr const TSymbolUniqueId BuiltInId::cos_Float3;
+constexpr const TSymbolUniqueId BuiltInId::cos_Float4;
+constexpr const TSymbolUniqueId BuiltInId::tan_Float1;
+constexpr const TSymbolUniqueId BuiltInId::tan_Float2;
+constexpr const TSymbolUniqueId BuiltInId::tan_Float3;
+constexpr const TSymbolUniqueId BuiltInId::tan_Float4;
+constexpr const TSymbolUniqueId BuiltInId::asin_Float1;
+constexpr const TSymbolUniqueId BuiltInId::asin_Float2;
+constexpr const TSymbolUniqueId BuiltInId::asin_Float3;
+constexpr const TSymbolUniqueId BuiltInId::asin_Float4;
+constexpr const TSymbolUniqueId BuiltInId::acos_Float1;
+constexpr const TSymbolUniqueId BuiltInId::acos_Float2;
+constexpr const TSymbolUniqueId BuiltInId::acos_Float3;
+constexpr const TSymbolUniqueId BuiltInId::acos_Float4;
+constexpr const TSymbolUniqueId BuiltInId::atan_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::atan_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::atan_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::atan_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::atan_Float1;
+constexpr const TSymbolUniqueId BuiltInId::atan_Float2;
+constexpr const TSymbolUniqueId BuiltInId::atan_Float3;
+constexpr const TSymbolUniqueId BuiltInId::atan_Float4;
+constexpr const TSymbolUniqueId BuiltInId::sinh_Float1;
+constexpr const TSymbolUniqueId BuiltInId::sinh_Float2;
+constexpr const TSymbolUniqueId BuiltInId::sinh_Float3;
+constexpr const TSymbolUniqueId BuiltInId::sinh_Float4;
+constexpr const TSymbolUniqueId BuiltInId::cosh_Float1;
+constexpr const TSymbolUniqueId BuiltInId::cosh_Float2;
+constexpr const TSymbolUniqueId BuiltInId::cosh_Float3;
+constexpr const TSymbolUniqueId BuiltInId::cosh_Float4;
+constexpr const TSymbolUniqueId BuiltInId::tanh_Float1;
+constexpr const TSymbolUniqueId BuiltInId::tanh_Float2;
+constexpr const TSymbolUniqueId BuiltInId::tanh_Float3;
+constexpr const TSymbolUniqueId BuiltInId::tanh_Float4;
+constexpr const TSymbolUniqueId BuiltInId::asinh_Float1;
+constexpr const TSymbolUniqueId BuiltInId::asinh_Float2;
+constexpr const TSymbolUniqueId BuiltInId::asinh_Float3;
+constexpr const TSymbolUniqueId BuiltInId::asinh_Float4;
+constexpr const TSymbolUniqueId BuiltInId::acosh_Float1;
+constexpr const TSymbolUniqueId BuiltInId::acosh_Float2;
+constexpr const TSymbolUniqueId BuiltInId::acosh_Float3;
+constexpr const TSymbolUniqueId BuiltInId::acosh_Float4;
+constexpr const TSymbolUniqueId BuiltInId::atanh_Float1;
+constexpr const TSymbolUniqueId BuiltInId::atanh_Float2;
+constexpr const TSymbolUniqueId BuiltInId::atanh_Float3;
+constexpr const TSymbolUniqueId BuiltInId::atanh_Float4;
+constexpr const TSymbolUniqueId BuiltInId::pow_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::pow_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::pow_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::pow_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::exp_Float1;
+constexpr const TSymbolUniqueId BuiltInId::exp_Float2;
+constexpr const TSymbolUniqueId BuiltInId::exp_Float3;
+constexpr const TSymbolUniqueId BuiltInId::exp_Float4;
+constexpr const TSymbolUniqueId BuiltInId::log_Float1;
+constexpr const TSymbolUniqueId BuiltInId::log_Float2;
+constexpr const TSymbolUniqueId BuiltInId::log_Float3;
+constexpr const TSymbolUniqueId BuiltInId::log_Float4;
+constexpr const TSymbolUniqueId BuiltInId::exp2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::exp2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::exp2_Float3;
+constexpr const TSymbolUniqueId BuiltInId::exp2_Float4;
+constexpr const TSymbolUniqueId BuiltInId::log2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::log2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::log2_Float3;
+constexpr const TSymbolUniqueId BuiltInId::log2_Float4;
+constexpr const TSymbolUniqueId BuiltInId::sqrt_Float1;
+constexpr const TSymbolUniqueId BuiltInId::sqrt_Float2;
+constexpr const TSymbolUniqueId BuiltInId::sqrt_Float3;
+constexpr const TSymbolUniqueId BuiltInId::sqrt_Float4;
+constexpr const TSymbolUniqueId BuiltInId::inversesqrt_Float1;
+constexpr const TSymbolUniqueId BuiltInId::inversesqrt_Float2;
+constexpr const TSymbolUniqueId BuiltInId::inversesqrt_Float3;
+constexpr const TSymbolUniqueId BuiltInId::inversesqrt_Float4;
+constexpr const TSymbolUniqueId BuiltInId::abs_Float1;
+constexpr const TSymbolUniqueId BuiltInId::abs_Float2;
+constexpr const TSymbolUniqueId BuiltInId::abs_Float3;
+constexpr const TSymbolUniqueId BuiltInId::abs_Float4;
+constexpr const TSymbolUniqueId BuiltInId::abs_Int1;
+constexpr const TSymbolUniqueId BuiltInId::abs_Int2;
+constexpr const TSymbolUniqueId BuiltInId::abs_Int3;
+constexpr const TSymbolUniqueId BuiltInId::abs_Int4;
+constexpr const TSymbolUniqueId BuiltInId::sign_Float1;
+constexpr const TSymbolUniqueId BuiltInId::sign_Float2;
+constexpr const TSymbolUniqueId BuiltInId::sign_Float3;
+constexpr const TSymbolUniqueId BuiltInId::sign_Float4;
+constexpr const TSymbolUniqueId BuiltInId::sign_Int1;
+constexpr const TSymbolUniqueId BuiltInId::sign_Int2;
+constexpr const TSymbolUniqueId BuiltInId::sign_Int3;
+constexpr const TSymbolUniqueId BuiltInId::sign_Int4;
+constexpr const TSymbolUniqueId BuiltInId::floor_Float1;
+constexpr const TSymbolUniqueId BuiltInId::floor_Float2;
+constexpr const TSymbolUniqueId BuiltInId::floor_Float3;
+constexpr const TSymbolUniqueId BuiltInId::floor_Float4;
+constexpr const TSymbolUniqueId BuiltInId::trunc_Float1;
+constexpr const TSymbolUniqueId BuiltInId::trunc_Float2;
+constexpr const TSymbolUniqueId BuiltInId::trunc_Float3;
+constexpr const TSymbolUniqueId BuiltInId::trunc_Float4;
+constexpr const TSymbolUniqueId BuiltInId::round_Float1;
+constexpr const TSymbolUniqueId BuiltInId::round_Float2;
+constexpr const TSymbolUniqueId BuiltInId::round_Float3;
+constexpr const TSymbolUniqueId BuiltInId::round_Float4;
+constexpr const TSymbolUniqueId BuiltInId::roundEven_Float1;
+constexpr const TSymbolUniqueId BuiltInId::roundEven_Float2;
+constexpr const TSymbolUniqueId BuiltInId::roundEven_Float3;
+constexpr const TSymbolUniqueId BuiltInId::roundEven_Float4;
+constexpr const TSymbolUniqueId BuiltInId::ceil_Float1;
+constexpr const TSymbolUniqueId BuiltInId::ceil_Float2;
+constexpr const TSymbolUniqueId BuiltInId::ceil_Float3;
+constexpr const TSymbolUniqueId BuiltInId::ceil_Float4;
+constexpr const TSymbolUniqueId BuiltInId::fract_Float1;
+constexpr const TSymbolUniqueId BuiltInId::fract_Float2;
+constexpr const TSymbolUniqueId BuiltInId::fract_Float3;
+constexpr const TSymbolUniqueId BuiltInId::fract_Float4;
+constexpr const TSymbolUniqueId BuiltInId::mod_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::mod_Float2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::mod_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::mod_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::mod_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::mod_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::mod_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::min_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::min_Float2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::min_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::min_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::min_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::min_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::min_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::min_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::min_Int2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::min_Int3_Int3;
+constexpr const TSymbolUniqueId BuiltInId::min_Int4_Int4;
+constexpr const TSymbolUniqueId BuiltInId::min_Int2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::min_Int3_Int1;
+constexpr const TSymbolUniqueId BuiltInId::min_Int4_Int1;
+constexpr const TSymbolUniqueId BuiltInId::min_UInt1_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::min_UInt2_UInt2;
+constexpr const TSymbolUniqueId BuiltInId::min_UInt3_UInt3;
+constexpr const TSymbolUniqueId BuiltInId::min_UInt4_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::min_UInt2_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::min_UInt3_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::min_UInt4_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::max_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::max_Float2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::max_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::max_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::max_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::max_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::max_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::max_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::max_Int2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::max_Int3_Int3;
+constexpr const TSymbolUniqueId BuiltInId::max_Int4_Int4;
+constexpr const TSymbolUniqueId BuiltInId::max_Int2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::max_Int3_Int1;
+constexpr const TSymbolUniqueId BuiltInId::max_Int4_Int1;
+constexpr const TSymbolUniqueId BuiltInId::max_UInt1_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::max_UInt2_UInt2;
+constexpr const TSymbolUniqueId BuiltInId::max_UInt3_UInt3;
+constexpr const TSymbolUniqueId BuiltInId::max_UInt4_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::max_UInt2_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::max_UInt3_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::max_UInt4_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::clamp_Float1_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::clamp_Float2_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::clamp_Float3_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::clamp_Float4_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::clamp_Float2_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::clamp_Float3_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::clamp_Float4_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::clamp_Int1_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::clamp_Int2_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::clamp_Int3_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::clamp_Int4_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::clamp_Int2_Int2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::clamp_Int3_Int3_Int3;
+constexpr const TSymbolUniqueId BuiltInId::clamp_Int4_Int4_Int4;
+constexpr const TSymbolUniqueId BuiltInId::clamp_UInt1_UInt1_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::clamp_UInt2_UInt1_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::clamp_UInt3_UInt1_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::clamp_UInt4_UInt1_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::clamp_UInt2_UInt2_UInt2;
+constexpr const TSymbolUniqueId BuiltInId::clamp_UInt3_UInt3_UInt3;
+constexpr const TSymbolUniqueId BuiltInId::clamp_UInt4_UInt4_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::mix_Float1_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::mix_Float2_Float2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::mix_Float3_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::mix_Float4_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::mix_Float2_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::mix_Float3_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::mix_Float4_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::mix_Float1_Float1_Bool1;
+constexpr const TSymbolUniqueId BuiltInId::mix_Float2_Float2_Bool2;
+constexpr const TSymbolUniqueId BuiltInId::mix_Float3_Float3_Bool3;
+constexpr const TSymbolUniqueId BuiltInId::mix_Float4_Float4_Bool4;
+constexpr const TSymbolUniqueId BuiltInId::step_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::step_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::step_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::step_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::step_Float1_Float2;
+constexpr const TSymbolUniqueId BuiltInId::step_Float1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::step_Float1_Float4;
+constexpr const TSymbolUniqueId BuiltInId::smoothstep_Float1_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::smoothstep_Float2_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::smoothstep_Float3_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::smoothstep_Float4_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::smoothstep_Float1_Float1_Float2;
+constexpr const TSymbolUniqueId BuiltInId::smoothstep_Float1_Float1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::smoothstep_Float1_Float1_Float4;
+constexpr const TSymbolUniqueId BuiltInId::modf_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::modf_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::modf_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::modf_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::isnan_Float1;
+constexpr const TSymbolUniqueId BuiltInId::isnan_Float2;
+constexpr const TSymbolUniqueId BuiltInId::isnan_Float3;
+constexpr const TSymbolUniqueId BuiltInId::isnan_Float4;
+constexpr const TSymbolUniqueId BuiltInId::isinf_Float1;
+constexpr const TSymbolUniqueId BuiltInId::isinf_Float2;
+constexpr const TSymbolUniqueId BuiltInId::isinf_Float3;
+constexpr const TSymbolUniqueId BuiltInId::isinf_Float4;
+constexpr const TSymbolUniqueId BuiltInId::floatBitsToInt_Float1;
+constexpr const TSymbolUniqueId BuiltInId::floatBitsToInt_Float2;
+constexpr const TSymbolUniqueId BuiltInId::floatBitsToInt_Float3;
+constexpr const TSymbolUniqueId BuiltInId::floatBitsToInt_Float4;
+constexpr const TSymbolUniqueId BuiltInId::floatBitsToUint_Float1;
+constexpr const TSymbolUniqueId BuiltInId::floatBitsToUint_Float2;
+constexpr const TSymbolUniqueId BuiltInId::floatBitsToUint_Float3;
+constexpr const TSymbolUniqueId BuiltInId::floatBitsToUint_Float4;
+constexpr const TSymbolUniqueId BuiltInId::intBitsToFloat_Int1;
+constexpr const TSymbolUniqueId BuiltInId::intBitsToFloat_Int2;
+constexpr const TSymbolUniqueId BuiltInId::intBitsToFloat_Int3;
+constexpr const TSymbolUniqueId BuiltInId::intBitsToFloat_Int4;
+constexpr const TSymbolUniqueId BuiltInId::uintBitsToFloat_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::uintBitsToFloat_UInt2;
+constexpr const TSymbolUniqueId BuiltInId::uintBitsToFloat_UInt3;
+constexpr const TSymbolUniqueId BuiltInId::uintBitsToFloat_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::frexp_Float1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::frexp_Float2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::frexp_Float3_Int3;
+constexpr const TSymbolUniqueId BuiltInId::frexp_Float4_Int4;
+constexpr const TSymbolUniqueId BuiltInId::ldexp_Float1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::ldexp_Float2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::ldexp_Float3_Int3;
+constexpr const TSymbolUniqueId BuiltInId::ldexp_Float4_Int4;
+constexpr const TSymbolUniqueId BuiltInId::packSnorm2x16_Float2;
+constexpr const TSymbolUniqueId BuiltInId::packUnorm2x16_Float2;
+constexpr const TSymbolUniqueId BuiltInId::packHalf2x16_Float2;
+constexpr const TSymbolUniqueId BuiltInId::unpackSnorm2x16_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::unpackUnorm2x16_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::unpackHalf2x16_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::packUnorm4x8_Float4;
+constexpr const TSymbolUniqueId BuiltInId::packSnorm4x8_Float4;
+constexpr const TSymbolUniqueId BuiltInId::unpackUnorm4x8_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::unpackSnorm4x8_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::length_Float1;
+constexpr const TSymbolUniqueId BuiltInId::length_Float2;
+constexpr const TSymbolUniqueId BuiltInId::length_Float3;
+constexpr const TSymbolUniqueId BuiltInId::length_Float4;
+constexpr const TSymbolUniqueId BuiltInId::distance_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::distance_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::distance_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::distance_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::dot_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::dot_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::dot_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::dot_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::cross_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::normalize_Float1;
+constexpr const TSymbolUniqueId BuiltInId::normalize_Float2;
+constexpr const TSymbolUniqueId BuiltInId::normalize_Float3;
+constexpr const TSymbolUniqueId BuiltInId::normalize_Float4;
+constexpr const TSymbolUniqueId BuiltInId::faceforward_Float1_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::faceforward_Float2_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::faceforward_Float3_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::faceforward_Float4_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::reflect_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::reflect_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::reflect_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::reflect_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::refract_Float1_Float1_Float1;
+constexpr const TSymbolUniqueId BuiltInId::refract_Float2_Float2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::refract_Float3_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::refract_Float4_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::matrixCompMult_Float2x2_Float2x2;
+constexpr const TSymbolUniqueId BuiltInId::matrixCompMult_Float3x3_Float3x3;
+constexpr const TSymbolUniqueId BuiltInId::matrixCompMult_Float4x4_Float4x4;
+constexpr const TSymbolUniqueId BuiltInId::matrixCompMult_Float2x3_Float2x3;
+constexpr const TSymbolUniqueId BuiltInId::matrixCompMult_Float3x2_Float3x2;
+constexpr const TSymbolUniqueId BuiltInId::matrixCompMult_Float2x4_Float2x4;
+constexpr const TSymbolUniqueId BuiltInId::matrixCompMult_Float4x2_Float4x2;
+constexpr const TSymbolUniqueId BuiltInId::matrixCompMult_Float3x4_Float3x4;
+constexpr const TSymbolUniqueId BuiltInId::matrixCompMult_Float4x3_Float4x3;
+constexpr const TSymbolUniqueId BuiltInId::outerProduct_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::outerProduct_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::outerProduct_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::outerProduct_Float3_Float2;
+constexpr const TSymbolUniqueId BuiltInId::outerProduct_Float2_Float3;
+constexpr const TSymbolUniqueId BuiltInId::outerProduct_Float4_Float2;
+constexpr const TSymbolUniqueId BuiltInId::outerProduct_Float2_Float4;
+constexpr const TSymbolUniqueId BuiltInId::outerProduct_Float4_Float3;
+constexpr const TSymbolUniqueId BuiltInId::outerProduct_Float3_Float4;
+constexpr const TSymbolUniqueId BuiltInId::transpose_Float2x2;
+constexpr const TSymbolUniqueId BuiltInId::transpose_Float3x3;
+constexpr const TSymbolUniqueId BuiltInId::transpose_Float4x4;
+constexpr const TSymbolUniqueId BuiltInId::transpose_Float3x2;
+constexpr const TSymbolUniqueId BuiltInId::transpose_Float2x3;
+constexpr const TSymbolUniqueId BuiltInId::transpose_Float4x2;
+constexpr const TSymbolUniqueId BuiltInId::transpose_Float2x4;
+constexpr const TSymbolUniqueId BuiltInId::transpose_Float4x3;
+constexpr const TSymbolUniqueId BuiltInId::transpose_Float3x4;
+constexpr const TSymbolUniqueId BuiltInId::determinant_Float2x2;
+constexpr const TSymbolUniqueId BuiltInId::determinant_Float3x3;
+constexpr const TSymbolUniqueId BuiltInId::determinant_Float4x4;
+constexpr const TSymbolUniqueId BuiltInId::inverse_Float2x2;
+constexpr const TSymbolUniqueId BuiltInId::inverse_Float3x3;
+constexpr const TSymbolUniqueId BuiltInId::inverse_Float4x4;
+constexpr const TSymbolUniqueId BuiltInId::lessThan_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::lessThan_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::lessThan_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::lessThan_Int2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::lessThan_Int3_Int3;
+constexpr const TSymbolUniqueId BuiltInId::lessThan_Int4_Int4;
+constexpr const TSymbolUniqueId BuiltInId::lessThan_UInt2_UInt2;
+constexpr const TSymbolUniqueId BuiltInId::lessThan_UInt3_UInt3;
+constexpr const TSymbolUniqueId BuiltInId::lessThan_UInt4_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::lessThanEqual_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::lessThanEqual_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::lessThanEqual_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::lessThanEqual_Int2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::lessThanEqual_Int3_Int3;
+constexpr const TSymbolUniqueId BuiltInId::lessThanEqual_Int4_Int4;
+constexpr const TSymbolUniqueId BuiltInId::lessThanEqual_UInt2_UInt2;
+constexpr const TSymbolUniqueId BuiltInId::lessThanEqual_UInt3_UInt3;
+constexpr const TSymbolUniqueId BuiltInId::lessThanEqual_UInt4_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::greaterThan_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::greaterThan_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::greaterThan_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::greaterThan_Int2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::greaterThan_Int3_Int3;
+constexpr const TSymbolUniqueId BuiltInId::greaterThan_Int4_Int4;
+constexpr const TSymbolUniqueId BuiltInId::greaterThan_UInt2_UInt2;
+constexpr const TSymbolUniqueId BuiltInId::greaterThan_UInt3_UInt3;
+constexpr const TSymbolUniqueId BuiltInId::greaterThan_UInt4_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::greaterThanEqual_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::greaterThanEqual_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::greaterThanEqual_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::greaterThanEqual_Int2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::greaterThanEqual_Int3_Int3;
+constexpr const TSymbolUniqueId BuiltInId::greaterThanEqual_Int4_Int4;
+constexpr const TSymbolUniqueId BuiltInId::greaterThanEqual_UInt2_UInt2;
+constexpr const TSymbolUniqueId BuiltInId::greaterThanEqual_UInt3_UInt3;
+constexpr const TSymbolUniqueId BuiltInId::greaterThanEqual_UInt4_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::equal_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::equal_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::equal_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::equal_Int2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::equal_Int3_Int3;
+constexpr const TSymbolUniqueId BuiltInId::equal_Int4_Int4;
+constexpr const TSymbolUniqueId BuiltInId::equal_UInt2_UInt2;
+constexpr const TSymbolUniqueId BuiltInId::equal_UInt3_UInt3;
+constexpr const TSymbolUniqueId BuiltInId::equal_UInt4_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::equal_Bool2_Bool2;
+constexpr const TSymbolUniqueId BuiltInId::equal_Bool3_Bool3;
+constexpr const TSymbolUniqueId BuiltInId::equal_Bool4_Bool4;
+constexpr const TSymbolUniqueId BuiltInId::notEqual_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::notEqual_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::notEqual_Float4_Float4;
+constexpr const TSymbolUniqueId BuiltInId::notEqual_Int2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::notEqual_Int3_Int3;
+constexpr const TSymbolUniqueId BuiltInId::notEqual_Int4_Int4;
+constexpr const TSymbolUniqueId BuiltInId::notEqual_UInt2_UInt2;
+constexpr const TSymbolUniqueId BuiltInId::notEqual_UInt3_UInt3;
+constexpr const TSymbolUniqueId BuiltInId::notEqual_UInt4_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::notEqual_Bool2_Bool2;
+constexpr const TSymbolUniqueId BuiltInId::notEqual_Bool3_Bool3;
+constexpr const TSymbolUniqueId BuiltInId::notEqual_Bool4_Bool4;
+constexpr const TSymbolUniqueId BuiltInId::any_Bool2;
+constexpr const TSymbolUniqueId BuiltInId::any_Bool3;
+constexpr const TSymbolUniqueId BuiltInId::any_Bool4;
+constexpr const TSymbolUniqueId BuiltInId::all_Bool2;
+constexpr const TSymbolUniqueId BuiltInId::all_Bool3;
+constexpr const TSymbolUniqueId BuiltInId::all_Bool4;
+constexpr const TSymbolUniqueId BuiltInId::notFunc_Bool2;
+constexpr const TSymbolUniqueId BuiltInId::notFunc_Bool3;
+constexpr const TSymbolUniqueId BuiltInId::notFunc_Bool4;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldExtract_Int1_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldExtract_Int2_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldExtract_Int3_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldExtract_Int4_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldExtract_UInt1_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldExtract_UInt2_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldExtract_UInt3_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldExtract_UInt4_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldInsert_Int1_Int1_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldInsert_Int2_Int2_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldInsert_Int3_Int3_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldInsert_Int4_Int4_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldInsert_UInt1_UInt1_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldInsert_UInt2_UInt2_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldInsert_UInt3_UInt3_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldInsert_UInt4_UInt4_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldReverse_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldReverse_Int2;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldReverse_Int3;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldReverse_Int4;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldReverse_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldReverse_UInt2;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldReverse_UInt3;
+constexpr const TSymbolUniqueId BuiltInId::bitfieldReverse_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::bitCount_Int1;
+constexpr const TSymbolUniqueId BuiltInId::bitCount_Int2;
+constexpr const TSymbolUniqueId BuiltInId::bitCount_Int3;
+constexpr const TSymbolUniqueId BuiltInId::bitCount_Int4;
+constexpr const TSymbolUniqueId BuiltInId::bitCount_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::bitCount_UInt2;
+constexpr const TSymbolUniqueId BuiltInId::bitCount_UInt3;
+constexpr const TSymbolUniqueId BuiltInId::bitCount_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::findLSB_Int1;
+constexpr const TSymbolUniqueId BuiltInId::findLSB_Int2;
+constexpr const TSymbolUniqueId BuiltInId::findLSB_Int3;
+constexpr const TSymbolUniqueId BuiltInId::findLSB_Int4;
+constexpr const TSymbolUniqueId BuiltInId::findLSB_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::findLSB_UInt2;
+constexpr const TSymbolUniqueId BuiltInId::findLSB_UInt3;
+constexpr const TSymbolUniqueId BuiltInId::findLSB_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::findMSB_Int1;
+constexpr const TSymbolUniqueId BuiltInId::findMSB_Int2;
+constexpr const TSymbolUniqueId BuiltInId::findMSB_Int3;
+constexpr const TSymbolUniqueId BuiltInId::findMSB_Int4;
+constexpr const TSymbolUniqueId BuiltInId::findMSB_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::findMSB_UInt2;
+constexpr const TSymbolUniqueId BuiltInId::findMSB_UInt3;
+constexpr const TSymbolUniqueId BuiltInId::findMSB_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::uaddCarry_UInt1_UInt1_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::uaddCarry_UInt2_UInt2_UInt2;
+constexpr const TSymbolUniqueId BuiltInId::uaddCarry_UInt3_UInt3_UInt3;
+constexpr const TSymbolUniqueId BuiltInId::uaddCarry_UInt4_UInt4_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::usubBorrow_UInt1_UInt1_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::usubBorrow_UInt2_UInt2_UInt2;
+constexpr const TSymbolUniqueId BuiltInId::usubBorrow_UInt3_UInt3_UInt3;
+constexpr const TSymbolUniqueId BuiltInId::usubBorrow_UInt4_UInt4_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::umulExtended_UInt2_UInt2_UInt2_UInt2;
+constexpr const TSymbolUniqueId BuiltInId::umulExtended_UInt3_UInt3_UInt3_UInt3;
+constexpr const TSymbolUniqueId BuiltInId::umulExtended_UInt4_UInt4_UInt4_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::imulExtended_Int1_Int1_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::imulExtended_Int2_Int2_Int2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::imulExtended_Int3_Int3_Int3_Int3;
+constexpr const TSymbolUniqueId BuiltInId::imulExtended_Int4_Int4_Int4_Int4;
+constexpr const TSymbolUniqueId BuiltInId::texture2D_Sampler2D1_Float2;
+constexpr const TSymbolUniqueId BuiltInId::texture2DProj_Sampler2D1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::texture2DProj_Sampler2D1_Float4;
+constexpr const TSymbolUniqueId BuiltInId::textureCube_SamplerCube1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::texture2D_SamplerExternalOES1_Float2;
+constexpr const TSymbolUniqueId BuiltInId::texture2DProj_SamplerExternalOES1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::texture2DProj_SamplerExternalOES1_Float4;
+constexpr const TSymbolUniqueId BuiltInId::texture2DRect_Sampler2DRect1_Float2;
+constexpr const TSymbolUniqueId BuiltInId::texture2DRectProj_Sampler2DRect1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::texture2DRectProj_Sampler2DRect1_Float4;
+constexpr const TSymbolUniqueId BuiltInId::texture_Sampler2DRect1_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_Sampler2DRect1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_Sampler2DRect1_Float4;
+constexpr const TSymbolUniqueId BuiltInId::texture2DGradEXT_Sampler2D1_Float2_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::texture2DProjGradEXT_Sampler2D1_Float3_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::texture2DProjGradEXT_Sampler2D1_Float4_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureCubeGradEXT_SamplerCube1_Float3_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::texture2D_Sampler2D1_Float2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture2DProj_Sampler2D1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture2DProj_Sampler2D1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureCube_SamplerCube1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::dFdxExt_Float1;
+constexpr const TSymbolUniqueId BuiltInId::dFdxExt_Float2;
+constexpr const TSymbolUniqueId BuiltInId::dFdxExt_Float3;
+constexpr const TSymbolUniqueId BuiltInId::dFdxExt_Float4;
+constexpr const TSymbolUniqueId BuiltInId::dFdyExt_Float1;
+constexpr const TSymbolUniqueId BuiltInId::dFdyExt_Float2;
+constexpr const TSymbolUniqueId BuiltInId::dFdyExt_Float3;
+constexpr const TSymbolUniqueId BuiltInId::dFdyExt_Float4;
+constexpr const TSymbolUniqueId BuiltInId::fwidthExt_Float1;
+constexpr const TSymbolUniqueId BuiltInId::fwidthExt_Float2;
+constexpr const TSymbolUniqueId BuiltInId::fwidthExt_Float3;
+constexpr const TSymbolUniqueId BuiltInId::fwidthExt_Float4;
+constexpr const TSymbolUniqueId BuiltInId::texture2DLodEXT_Sampler2D1_Float2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture2DProjLodEXT_Sampler2D1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture2DProjLodEXT_Sampler2D1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureCubeLodEXT_SamplerCube1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture2DLod_Sampler2D1_Float2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture2DProjLod_Sampler2D1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture2DProjLod_Sampler2D1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureCubeLod_SamplerCube1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_Sampler2D1_Float2;
+constexpr const TSymbolUniqueId BuiltInId::texture_ISampler2D1_Float2;
+constexpr const TSymbolUniqueId BuiltInId::texture_USampler2D1_Float2;
+constexpr const TSymbolUniqueId BuiltInId::texture_Sampler3D1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::texture_ISampler3D1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::texture_USampler3D1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::texture_SamplerCube1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::texture_ISamplerCube1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::texture_USamplerCube1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::texture_Sampler2DArray1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::texture_ISampler2DArray1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::texture_USampler2DArray1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_Sampler2D1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_ISampler2D1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_USampler2D1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_Sampler2D1_Float4;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_ISampler2D1_Float4;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_USampler2D1_Float4;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_Sampler3D1_Float4;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_ISampler3D1_Float4;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_USampler3D1_Float4;
+constexpr const TSymbolUniqueId BuiltInId::textureLod_Sampler2D1_Float2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureLod_ISampler2D1_Float2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureLod_USampler2D1_Float2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureLod_Sampler3D1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureLod_ISampler3D1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureLod_USampler3D1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureLod_SamplerCube1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureLod_ISamplerCube1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureLod_USamplerCube1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureLod_Sampler2DArray1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureLod_ISampler2DArray1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureLod_USampler2DArray1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_Sampler2DShadow1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::texture_SamplerCubeShadow1_Float4;
+constexpr const TSymbolUniqueId BuiltInId::texture_Sampler2DArrayShadow1_Float4;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_Sampler2DShadow1_Float4;
+constexpr const TSymbolUniqueId BuiltInId::textureLod_Sampler2DShadow1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_Sampler2D1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_ISampler2D1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_USampler2D1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_Sampler3D1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_ISampler3D1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_USampler3D1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_SamplerCube1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_ISamplerCube1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_USamplerCube1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_Sampler2DArray1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_ISampler2DArray1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_USampler2DArray1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_Sampler2DShadow1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_SamplerCubeShadow1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_Sampler2DArrayShadow1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_Sampler2DMS1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_ISampler2DMS1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_USampler2DMS1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLod_Sampler2D1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLod_ISampler2D1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLod_USampler2D1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLod_Sampler2D1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLod_ISampler2D1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLod_USampler2D1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLod_Sampler3D1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLod_ISampler3D1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLod_USampler3D1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLod_Sampler2DShadow1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texelFetch_Sampler2D1_Int2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::texelFetch_ISampler2D1_Int2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::texelFetch_USampler2D1_Int2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::texelFetch_Sampler3D1_Int3_Int1;
+constexpr const TSymbolUniqueId BuiltInId::texelFetch_ISampler3D1_Int3_Int1;
+constexpr const TSymbolUniqueId BuiltInId::texelFetch_USampler3D1_Int3_Int1;
+constexpr const TSymbolUniqueId BuiltInId::texelFetch_Sampler2DArray1_Int3_Int1;
+constexpr const TSymbolUniqueId BuiltInId::texelFetch_ISampler2DArray1_Int3_Int1;
+constexpr const TSymbolUniqueId BuiltInId::texelFetch_USampler2DArray1_Int3_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureGrad_Sampler2D1_Float2_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureGrad_ISampler2D1_Float2_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureGrad_USampler2D1_Float2_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureGrad_Sampler3D1_Float3_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureGrad_ISampler3D1_Float3_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureGrad_USampler3D1_Float3_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureGrad_SamplerCube1_Float3_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureGrad_ISamplerCube1_Float3_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureGrad_USamplerCube1_Float3_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureGrad_Sampler2DShadow1_Float3_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureGrad_SamplerCubeShadow1_Float4_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureGrad_Sampler2DArray1_Float3_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureGrad_ISampler2DArray1_Float3_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureGrad_USampler2DArray1_Float3_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureGrad_Sampler2DArrayShadow1_Float4_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjGrad_Sampler2D1_Float3_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjGrad_ISampler2D1_Float3_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjGrad_USampler2D1_Float3_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjGrad_Sampler2D1_Float4_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjGrad_ISampler2D1_Float4_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjGrad_USampler2D1_Float4_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjGrad_Sampler3D1_Float4_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureProjGrad_ISampler3D1_Float4_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureProjGrad_USampler3D1_Float4_Float3_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureProjGrad_Sampler2DShadow1_Float4_Float2_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_Sampler2D1_Float2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_ISampler2D1_Float2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_USampler2D1_Float2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_Sampler3D1_Float3_Int3;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_ISampler3D1_Float3_Int3;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_USampler3D1_Float3_Int3;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_Sampler2DShadow1_Float3_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_Sampler2DArray1_Float3_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_ISampler2DArray1_Float3_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_USampler2DArray1_Float3_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_Sampler2D1_Float3_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_ISampler2D1_Float3_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_USampler2D1_Float3_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_Sampler2D1_Float4_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_ISampler2D1_Float4_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_USampler2D1_Float4_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_Sampler3D1_Float4_Int3;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_ISampler3D1_Float4_Int3;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_USampler3D1_Float4_Int3;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_Sampler2DShadow1_Float4_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureLodOffset_Sampler2D1_Float2_Float1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureLodOffset_ISampler2D1_Float2_Float1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureLodOffset_USampler2D1_Float2_Float1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureLodOffset_Sampler3D1_Float3_Float1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::textureLodOffset_ISampler3D1_Float3_Float1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::textureLodOffset_USampler3D1_Float3_Float1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::textureLodOffset_Sampler2DShadow1_Float3_Float1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureLodOffset_Sampler2DArray1_Float3_Float1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureLodOffset_ISampler2DArray1_Float3_Float1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureLodOffset_USampler2DArray1_Float3_Float1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLodOffset_Sampler2D1_Float3_Float1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLodOffset_ISampler2D1_Float3_Float1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLodOffset_USampler2D1_Float3_Float1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLodOffset_Sampler2D1_Float4_Float1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLodOffset_ISampler2D1_Float4_Float1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLodOffset_USampler2D1_Float4_Float1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLodOffset_Sampler3D1_Float4_Float1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLodOffset_ISampler3D1_Float4_Float1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLodOffset_USampler3D1_Float4_Float1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::textureProjLodOffset_Sampler2DShadow1_Float4_Float1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::texelFetchOffset_Sampler2D1_Int2_Int1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::texelFetchOffset_ISampler2D1_Int2_Int1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::texelFetchOffset_USampler2D1_Int2_Int1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::texelFetchOffset_Sampler3D1_Int3_Int1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::texelFetchOffset_ISampler3D1_Int3_Int1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::texelFetchOffset_USampler3D1_Int3_Int1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::texelFetchOffset_Sampler2DArray1_Int3_Int1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::texelFetchOffset_ISampler2DArray1_Int3_Int1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::texelFetchOffset_USampler2DArray1_Int3_Int1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureGradOffset_Sampler2D1_Float2_Float2_Float2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureGradOffset_ISampler2D1_Float2_Float2_Float2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureGradOffset_USampler2D1_Float2_Float2_Float2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureGradOffset_Sampler3D1_Float3_Float3_Float3_Int3;
+constexpr const TSymbolUniqueId BuiltInId::textureGradOffset_ISampler3D1_Float3_Float3_Float3_Int3;
+constexpr const TSymbolUniqueId BuiltInId::textureGradOffset_USampler3D1_Float3_Float3_Float3_Int3;
+constexpr const TSymbolUniqueId
+    BuiltInId::textureGradOffset_Sampler2DShadow1_Float3_Float2_Float2_Int2;
+constexpr const TSymbolUniqueId
+    BuiltInId::textureGradOffset_Sampler2DArray1_Float3_Float2_Float2_Int2;
+constexpr const TSymbolUniqueId
+    BuiltInId::textureGradOffset_ISampler2DArray1_Float3_Float2_Float2_Int2;
+constexpr const TSymbolUniqueId
+    BuiltInId::textureGradOffset_USampler2DArray1_Float3_Float2_Float2_Int2;
+constexpr const TSymbolUniqueId
+    BuiltInId::textureGradOffset_Sampler2DArrayShadow1_Float4_Float2_Float2_Int2;
+constexpr const TSymbolUniqueId
+    BuiltInId::textureProjGradOffset_Sampler2D1_Float3_Float2_Float2_Int2;
+constexpr const TSymbolUniqueId
+    BuiltInId::textureProjGradOffset_ISampler2D1_Float3_Float2_Float2_Int2;
+constexpr const TSymbolUniqueId
+    BuiltInId::textureProjGradOffset_USampler2D1_Float3_Float2_Float2_Int2;
+constexpr const TSymbolUniqueId
+    BuiltInId::textureProjGradOffset_Sampler2D1_Float4_Float2_Float2_Int2;
+constexpr const TSymbolUniqueId
+    BuiltInId::textureProjGradOffset_ISampler2D1_Float4_Float2_Float2_Int2;
+constexpr const TSymbolUniqueId
+    BuiltInId::textureProjGradOffset_USampler2D1_Float4_Float2_Float2_Int2;
+constexpr const TSymbolUniqueId
+    BuiltInId::textureProjGradOffset_Sampler3D1_Float4_Float3_Float3_Int3;
+constexpr const TSymbolUniqueId
+    BuiltInId::textureProjGradOffset_ISampler3D1_Float4_Float3_Float3_Int3;
+constexpr const TSymbolUniqueId
+    BuiltInId::textureProjGradOffset_USampler3D1_Float4_Float3_Float3_Int3;
+constexpr const TSymbolUniqueId
+    BuiltInId::textureProjGradOffset_Sampler2DShadow1_Float4_Float2_Float2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_Sampler2D1_Float2_Int2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_ISampler2D1_Float2_Int2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_USampler2D1_Float2_Int2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_Sampler3D1_Float3_Int3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_ISampler3D1_Float3_Int3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_USampler3D1_Float3_Int3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_Sampler2DShadow1_Float3_Int2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_Sampler2DArray1_Float3_Int2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_ISampler2DArray1_Float3_Int2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureOffset_USampler2DArray1_Float3_Int2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_Sampler2D1_Float3_Int2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_ISampler2D1_Float3_Int2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_USampler2D1_Float3_Int2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_Sampler2D1_Float4_Int2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_ISampler2D1_Float4_Int2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_USampler2D1_Float4_Int2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_Sampler3D1_Float4_Int3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_ISampler3D1_Float4_Int3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_USampler3D1_Float4_Int3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProjOffset_Sampler2DShadow1_Float4_Int2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_SamplerExternalOES1_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_SamplerExternalOES1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_SamplerExternalOES1_Float4;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_SamplerExternalOES1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::texelFetch_SamplerExternalOES1_Int2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::texture_SamplerExternal2DY2YEXT1_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_SamplerExternal2DY2YEXT1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_SamplerExternal2DY2YEXT1_Float4;
+constexpr const TSymbolUniqueId BuiltInId::rgb_2_yuv_Float3_YuvCscStandardEXT1;
+constexpr const TSymbolUniqueId BuiltInId::yuv_2_rgb_Float3_YuvCscStandardEXT1;
+constexpr const TSymbolUniqueId BuiltInId::textureSize_SamplerExternal2DY2YEXT1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::texelFetch_SamplerExternal2DY2YEXT1_Int2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::texture_Sampler2D1_Float2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_ISampler2D1_Float2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_USampler2D1_Float2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_Sampler3D1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_ISampler3D1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_USampler3D1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_SamplerCube1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_ISamplerCube1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_USamplerCube1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_Sampler2DArray1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_ISampler2DArray1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_USampler2DArray1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_Sampler2D1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_ISampler2D1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_USampler2D1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_Sampler2D1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_ISampler2D1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_USampler2D1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_Sampler3D1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_ISampler3D1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_USampler3D1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_Sampler2DShadow1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_SamplerCubeShadow1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_Sampler2DShadow1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_SamplerExternalOES1_Float2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_SamplerExternalOES1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_SamplerExternalOES1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texture_SamplerExternal2DY2YEXT1_Float2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_SamplerExternal2DY2YEXT1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureProj_SamplerExternal2DY2YEXT1_Float4_Float1;
+constexpr const TSymbolUniqueId BuiltInId::texelFetch_Sampler2DMS1_Int2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::texelFetch_ISampler2DMS1_Int2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::texelFetch_USampler2DMS1_Int2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_Sampler2D1_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_ISampler2D1_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_USampler2D1_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_Sampler2D1_Float2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_ISampler2D1_Float2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_USampler2D1_Float2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_Sampler2DArray1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_ISampler2DArray1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_USampler2DArray1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_Sampler2DArray1_Float3_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_ISampler2DArray1_Float3_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_USampler2DArray1_Float3_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_SamplerCube1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_ISamplerCube1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_USamplerCube1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_SamplerCube1_Float3_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_ISamplerCube1_Float3_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_USamplerCube1_Float3_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_Sampler2DShadow1_Float2;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_Sampler2DShadow1_Float2_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_Sampler2DArrayShadow1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_Sampler2DArrayShadow1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_SamplerCubeShadow1_Float3;
+constexpr const TSymbolUniqueId BuiltInId::textureGather_SamplerCubeShadow1_Float3_Float1;
+constexpr const TSymbolUniqueId BuiltInId::textureGatherOffset_Sampler2D1_Float2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureGatherOffset_ISampler2D1_Float2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureGatherOffset_USampler2D1_Float2_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureGatherOffset_Sampler2D1_Float2_Int2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureGatherOffset_ISampler2D1_Float2_Int2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureGatherOffset_USampler2D1_Float2_Int2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureGatherOffset_Sampler2DArray1_Float3_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureGatherOffset_ISampler2DArray1_Float3_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureGatherOffset_USampler2DArray1_Float3_Int2;
+constexpr const TSymbolUniqueId BuiltInId::textureGatherOffset_Sampler2DArray1_Float3_Int2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureGatherOffset_ISampler2DArray1_Float3_Int2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureGatherOffset_USampler2DArray1_Float3_Int2_Int1;
+constexpr const TSymbolUniqueId BuiltInId::textureGatherOffset_Sampler2DShadow1_Float2_Float1_Int2;
+constexpr const TSymbolUniqueId
+    BuiltInId::textureGatherOffset_Sampler2DArrayShadow1_Float3_Float1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::dFdx_Float1;
+constexpr const TSymbolUniqueId BuiltInId::dFdx_Float2;
+constexpr const TSymbolUniqueId BuiltInId::dFdx_Float3;
+constexpr const TSymbolUniqueId BuiltInId::dFdx_Float4;
+constexpr const TSymbolUniqueId BuiltInId::dFdy_Float1;
+constexpr const TSymbolUniqueId BuiltInId::dFdy_Float2;
+constexpr const TSymbolUniqueId BuiltInId::dFdy_Float3;
+constexpr const TSymbolUniqueId BuiltInId::dFdy_Float4;
+constexpr const TSymbolUniqueId BuiltInId::fwidth_Float1;
+constexpr const TSymbolUniqueId BuiltInId::fwidth_Float2;
+constexpr const TSymbolUniqueId BuiltInId::fwidth_Float3;
+constexpr const TSymbolUniqueId BuiltInId::fwidth_Float4;
+constexpr const TSymbolUniqueId BuiltInId::atomicCounter_AtomicCounter1;
+constexpr const TSymbolUniqueId BuiltInId::atomicCounterIncrement_AtomicCounter1;
+constexpr const TSymbolUniqueId BuiltInId::atomicCounterDecrement_AtomicCounter1;
+constexpr const TSymbolUniqueId BuiltInId::atomicAdd_UInt1_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::atomicAdd_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::atomicMin_UInt1_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::atomicMin_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::atomicMax_UInt1_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::atomicMax_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::atomicAnd_UInt1_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::atomicAnd_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::atomicOr_UInt1_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::atomicOr_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::atomicXor_UInt1_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::atomicXor_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::atomicExchange_UInt1_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::atomicExchange_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::atomicCompSwap_UInt1_UInt1_UInt1;
+constexpr const TSymbolUniqueId BuiltInId::atomicCompSwap_Int1_Int1_Int1;
+constexpr const TSymbolUniqueId BuiltInId::imageSize_Image2D1;
+constexpr const TSymbolUniqueId BuiltInId::imageSize_IImage2D1;
+constexpr const TSymbolUniqueId BuiltInId::imageSize_UImage2D1;
+constexpr const TSymbolUniqueId BuiltInId::imageSize_Image3D1;
+constexpr const TSymbolUniqueId BuiltInId::imageSize_IImage3D1;
+constexpr const TSymbolUniqueId BuiltInId::imageSize_UImage3D1;
+constexpr const TSymbolUniqueId BuiltInId::imageSize_Image2DArray1;
+constexpr const TSymbolUniqueId BuiltInId::imageSize_IImage2DArray1;
+constexpr const TSymbolUniqueId BuiltInId::imageSize_UImage2DArray1;
+constexpr const TSymbolUniqueId BuiltInId::imageSize_ImageCube1;
+constexpr const TSymbolUniqueId BuiltInId::imageSize_IImageCube1;
+constexpr const TSymbolUniqueId BuiltInId::imageSize_UImageCube1;
+constexpr const TSymbolUniqueId BuiltInId::imageLoad_Image2D1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::imageLoad_IImage2D1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::imageLoad_UImage2D1_Int2;
+constexpr const TSymbolUniqueId BuiltInId::imageLoad_Image3D1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::imageLoad_IImage3D1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::imageLoad_UImage3D1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::imageLoad_Image2DArray1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::imageLoad_IImage2DArray1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::imageLoad_UImage2DArray1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::imageLoad_ImageCube1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::imageLoad_IImageCube1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::imageLoad_UImageCube1_Int3;
+constexpr const TSymbolUniqueId BuiltInId::imageStore_Image2D1_Int2_Float4;
+constexpr const TSymbolUniqueId BuiltInId::imageStore_IImage2D1_Int2_Int4;
+constexpr const TSymbolUniqueId BuiltInId::imageStore_UImage2D1_Int2_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::imageStore_Image3D1_Int3_Float4;
+constexpr const TSymbolUniqueId BuiltInId::imageStore_IImage3D1_Int3_Int4;
+constexpr const TSymbolUniqueId BuiltInId::imageStore_UImage3D1_Int3_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::imageStore_Image2DArray1_Int3_Float4;
+constexpr const TSymbolUniqueId BuiltInId::imageStore_IImage2DArray1_Int3_Int4;
+constexpr const TSymbolUniqueId BuiltInId::imageStore_UImage2DArray1_Int3_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::imageStore_ImageCube1_Int3_Float4;
+constexpr const TSymbolUniqueId BuiltInId::imageStore_IImageCube1_Int3_Int4;
+constexpr const TSymbolUniqueId BuiltInId::imageStore_UImageCube1_Int3_UInt4;
+constexpr const TSymbolUniqueId BuiltInId::memoryBarrier;
+constexpr const TSymbolUniqueId BuiltInId::memoryBarrierAtomicCounter;
+constexpr const TSymbolUniqueId BuiltInId::memoryBarrierBuffer;
+constexpr const TSymbolUniqueId BuiltInId::memoryBarrierImage;
+constexpr const TSymbolUniqueId BuiltInId::barrier;
+constexpr const TSymbolUniqueId BuiltInId::memoryBarrierShared;
+constexpr const TSymbolUniqueId BuiltInId::groupMemoryBarrier;
+constexpr const TSymbolUniqueId BuiltInId::EmitVertex;
+constexpr const TSymbolUniqueId BuiltInId::EndPrimitive;
+constexpr const TSymbolUniqueId BuiltInId::gl_DepthRangeParameters;
+constexpr const TSymbolUniqueId BuiltInId::gl_DepthRange;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxVertexAttribs;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxVertexUniformVectors;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxVertexTextureImageUnits;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxCombinedTextureImageUnits;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxTextureImageUnits;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxFragmentUniformVectors;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxVaryingVectors;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxDrawBuffers;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxDualSourceDrawBuffersEXT;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxVertexOutputVectors;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxFragmentInputVectors;
+constexpr const TSymbolUniqueId BuiltInId::gl_MinProgramTexelOffset;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxProgramTexelOffset;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxImageUnits;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxVertexImageUniforms;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxFragmentImageUniforms;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxComputeImageUniforms;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxCombinedImageUniforms;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxCombinedShaderOutputResources;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxComputeWorkGroupCount;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxComputeWorkGroupSize;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxComputeUniformComponents;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxComputeTextureImageUnits;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxComputeAtomicCounters;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxComputeAtomicCounterBuffers;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxVertexAtomicCounters;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxFragmentAtomicCounters;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxCombinedAtomicCounters;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxAtomicCounterBindings;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxVertexAtomicCounterBuffers;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxFragmentAtomicCounterBuffers;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxCombinedAtomicCounterBuffers;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxAtomicCounterBufferSize;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxGeometryInputComponents;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxGeometryOutputComponents;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxGeometryImageUniforms;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxGeometryTextureImageUnits;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxGeometryOutputVertices;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxGeometryTotalOutputComponents;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxGeometryUniformComponents;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxGeometryAtomicCounters;
+constexpr const TSymbolUniqueId BuiltInId::gl_MaxGeometryAtomicCounterBuffers;
+constexpr const TSymbolUniqueId BuiltInId::gl_FragCoord;
+constexpr const TSymbolUniqueId BuiltInId::gl_FrontFacing;
+constexpr const TSymbolUniqueId BuiltInId::gl_PointCoord;
+constexpr const TSymbolUniqueId BuiltInId::gl_FragColor;
+constexpr const TSymbolUniqueId BuiltInId::gl_FragData;
+constexpr const TSymbolUniqueId BuiltInId::gl_FragDepth;
+constexpr const TSymbolUniqueId BuiltInId::gl_SecondaryFragColorEXT;
+constexpr const TSymbolUniqueId BuiltInId::gl_SecondaryFragDataEXT;
+constexpr const TSymbolUniqueId BuiltInId::gl_FragDepthEXT;
+constexpr const TSymbolUniqueId BuiltInId::gl_LastFragData;
+constexpr const TSymbolUniqueId BuiltInId::gl_LastFragColor;
+constexpr const TSymbolUniqueId BuiltInId::gl_LastFragDataNV;
+constexpr const TSymbolUniqueId BuiltInId::gl_LastFragColorARM;
+constexpr const TSymbolUniqueId BuiltInId::gl_PrimitiveID;
+constexpr const TSymbolUniqueId BuiltInId::gl_Layer;
+constexpr const TSymbolUniqueId BuiltInId::gl_Position;
+constexpr const TSymbolUniqueId BuiltInId::gl_PointSize;
+constexpr const TSymbolUniqueId BuiltInId::gl_InstanceID;
+constexpr const TSymbolUniqueId BuiltInId::gl_VertexID;
+constexpr const TSymbolUniqueId BuiltInId::gl_ViewportIndex;
+constexpr const TSymbolUniqueId BuiltInId::gl_LayerVS;
+constexpr const TSymbolUniqueId BuiltInId::gl_NumWorkGroups;
+constexpr const TSymbolUniqueId BuiltInId::gl_WorkGroupSize;
+constexpr const TSymbolUniqueId BuiltInId::gl_WorkGroupID;
+constexpr const TSymbolUniqueId BuiltInId::gl_LocalInvocationID;
+constexpr const TSymbolUniqueId BuiltInId::gl_GlobalInvocationID;
+constexpr const TSymbolUniqueId BuiltInId::gl_LocalInvocationIndex;
+constexpr const TSymbolUniqueId BuiltInId::gl_PrimitiveIDIn;
+constexpr const TSymbolUniqueId BuiltInId::gl_InvocationID;
+constexpr const TSymbolUniqueId BuiltInId::gl_PrimitiveIDGS;
+constexpr const TSymbolUniqueId BuiltInId::gl_LayerGS;
+constexpr const TSymbolUniqueId BuiltInId::gl_PerVertex;
+constexpr const TSymbolUniqueId BuiltInId::gl_in;
+constexpr const TSymbolUniqueId BuiltInId::gl_PerVertexOutBlock;
+constexpr const TSymbolUniqueId BuiltInId::gl_PositionGS;
+constexpr const TSymbolUniqueId BuiltInId::gl_ViewID_OVR;
+constexpr const TSymbolUniqueId BuiltInId::gl_ViewID_OVRESSL1;
+
+const int TSymbolTable::kLastBuiltInId = 1008;
+
+namespace BuiltInName
+{
+
+constexpr const ImmutableString _empty("");
+constexpr const ImmutableString EmitVertex("EmitVertex");
+constexpr const ImmutableString EndPrimitive("EndPrimitive");
+constexpr const ImmutableString abs("abs");
+constexpr const ImmutableString acos("acos");
+constexpr const ImmutableString acosh("acosh");
+constexpr const ImmutableString all("all");
+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 atomicCompSwap_0D0D0D("atomicCompSwap(0D0D0D");
+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 bitCount("bitCount");
+constexpr const ImmutableString bitfieldExtract("bitfieldExtract");
+constexpr const ImmutableString bitfieldExtract_0D0C0C("bitfieldExtract(0D0C0C");
+constexpr const ImmutableString bitfieldExtract_1C0C0C("bitfieldExtract(1C0C0C");
+constexpr const ImmutableString bitfieldInsert("bitfieldInsert");
+constexpr const ImmutableString bitfieldInsert_0C0C0C0C("bitfieldInsert(0C0C0C0C");
+constexpr const ImmutableString bitfieldInsert_0D0D0C0C("bitfieldInsert(0D0D0C0C");
+constexpr const ImmutableString bitfieldInsert_1C1C0C0C("bitfieldInsert(1C1C0C0C");
+constexpr const ImmutableString bitfieldInsert_1D1D0C0C("bitfieldInsert(1D1D0C0C");
+constexpr const ImmutableString bitfieldInsert_2C2C0C0C("bitfieldInsert(2C2C0C0C");
+constexpr const ImmutableString bitfieldInsert_2D2D0C0C("bitfieldInsert(2D2D0C0C");
+constexpr const ImmutableString bitfieldInsert_3C3C0C0C("bitfieldInsert(3C3C0C0C");
+constexpr const ImmutableString bitfieldInsert_3D3D0C0C("bitfieldInsert(3D3D0C0C");
+constexpr const ImmutableString bitfieldReverse("bitfieldReverse");
+constexpr const ImmutableString ceil("ceil");
+constexpr const ImmutableString clamp("clamp");
+constexpr const ImmutableString clamp_0D0D0D("clamp(0D0D0D");
+constexpr const ImmutableString clamp_1B0B0B("clamp(1B0B0B");
+constexpr const ImmutableString clamp_1B1B1B("clamp(1B1B1B");
+constexpr const ImmutableString clamp_1C0C0C("clamp(1C0C0C");
+constexpr const ImmutableString clamp_1C1C1C("clamp(1C1C1C");
+constexpr const ImmutableString clamp_2C2C2C("clamp(2C2C2C");
+constexpr const ImmutableString clamp_3B0B0B("clamp(3B0B0B");
+constexpr const ImmutableString clamp_3C0C0C("clamp(3C0C0C");
+constexpr const ImmutableString clamp_3D0D0D("clamp(3D0D0D");
+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 equal("equal");
+constexpr const ImmutableString exp("exp");
+constexpr const ImmutableString exp2("exp2");
+constexpr const ImmutableString faceforward("faceforward");
+constexpr const ImmutableString faceforward_1B1B1B("faceforward(1B1B1B");
+constexpr const ImmutableString faceforward_2B2B2B("faceforward(2B2B2B");
+constexpr const ImmutableString faceforward_3B3B3B("faceforward(3B3B3B");
+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 fract("fract");
+constexpr const ImmutableString frexp("frexp");
+constexpr const ImmutableString frexp_3B3C("frexp(3B3C");
+constexpr const ImmutableString fwidth("fwidth");
+constexpr const ImmutableString fwidthExt("fwidth");
+constexpr const ImmutableString gl_DepthRange("gl_DepthRange");
+constexpr const ImmutableString gl_DepthRangeParameters("gl_DepthRangeParameters");
+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_InstanceID("gl_InstanceID");
+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_MaxCombinedAtomicCounterBuffers(
+    "gl_MaxCombinedAtomicCounterBuffers");
+constexpr const ImmutableString gl_MaxCombinedAtomicCounters("gl_MaxCombinedAtomicCounters");
+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_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_MaxProgramTexelOffset("gl_MaxProgramTexelOffset");
+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_NumWorkGroups("gl_NumWorkGroups");
+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_SecondaryFragColorEXT("gl_SecondaryFragColorEXT");
+constexpr const ImmutableString gl_SecondaryFragDataEXT("gl_SecondaryFragDataEXT");
+constexpr const ImmutableString gl_VertexID("gl_VertexID");
+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 greaterThan("greaterThan");
+constexpr const ImmutableString greaterThanEqual("greaterThanEqual");
+constexpr const ImmutableString groupMemoryBarrier("groupMemoryBarrier");
+constexpr const ImmutableString imageLoad("imageLoad");
+constexpr const ImmutableString imageSize("imageSize");
+constexpr const ImmutableString imageStore("imageStore");
+constexpr const ImmutableString imageStore_0c1C3B("imageStore(0c1C3B");
+constexpr const ImmutableString imageStore_0d1C3C("imageStore(0d1C3C");
+constexpr const ImmutableString imageStore_0e1C3D("imageStore(0e1C3D");
+constexpr const ImmutableString imageStore_0l2C3B("imageStore(0l2C3B");
+constexpr const ImmutableString imageStore_0n2C3D("imageStore(0n2C3D");
+constexpr const ImmutableString imulExtended("imulExtended");
+constexpr const ImmutableString imulExtended_0C0C0C0C("imulExtended(0C0C0C0C");
+constexpr const ImmutableString imulExtended_1C1C1C1C("imulExtended(1C1C1C1C");
+constexpr const ImmutableString imulExtended_2C2C2C2C("imulExtended(2C2C2C2C");
+constexpr const ImmutableString imulExtended_3C3C3C3C("imulExtended(3C3C3C3C");
+constexpr const ImmutableString intBitsToFloat("intBitsToFloat");
+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 mix_0B0B0E("mix(0B0B0E");
+constexpr const ImmutableString mix_1B1B1B("mix(1B1B1B");
+constexpr const ImmutableString mix_3B3B0B("mix(3B3B0B");
+constexpr const ImmutableString mix_3B3B3B("mix(3B3B3B");
+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 pow("pow");
+constexpr const ImmutableString radians("radians");
+constexpr const ImmutableString reflect("reflect");
+constexpr const ImmutableString refract("refract");
+constexpr const ImmutableString refract_3B3B0B("refract(3B3B0B");
+constexpr const ImmutableString rgb_2_yuv("rgb_2_yuv");
+constexpr const ImmutableString round("round");
+constexpr const ImmutableString roundEven("roundEven");
+constexpr const ImmutableString sign("sign");
+constexpr const ImmutableString sin("sin");
+constexpr const ImmutableString sinh("sinh");
+constexpr const ImmutableString smoothstep("smoothstep");
+constexpr const ImmutableString smoothstep_1B1B1B("smoothstep(1B1B1B");
+constexpr const ImmutableString smoothstep_3B3B3B("smoothstep(3B3B3B");
+constexpr const ImmutableString sqrt("sqrt");
+constexpr const ImmutableString step("step");
+constexpr const ImmutableString tan("tan");
+constexpr const ImmutableString tanh("tanh");
+constexpr const ImmutableString texelFetch("texelFetch");
+constexpr const ImmutableString texelFetchOffset("texelFetchOffset");
+constexpr const ImmutableString texelFetchOffset_0H1C0C1C("texelFetchOffset(0H1C0C1C");
+constexpr const ImmutableString texelFetchOffset_0I2C0C2C("texelFetchOffset(0I2C0C2C");
+constexpr const ImmutableString texelFetchOffset_0K2C0C1C("texelFetchOffset(0K2C0C1C");
+constexpr const ImmutableString texelFetchOffset_0P1C0C1C("texelFetchOffset(0P1C0C1C");
+constexpr const ImmutableString texelFetchOffset_0Q2C0C2C("texelFetchOffset(0Q2C0C2C");
+constexpr const ImmutableString texelFetchOffset_0S2C0C1C("texelFetchOffset(0S2C0C1C");
+constexpr const ImmutableString texelFetchOffset_0U1C0C1C("texelFetchOffset(0U1C0C1C");
+constexpr const ImmutableString texelFetchOffset_0V2C0C2C("texelFetchOffset(0V2C0C2C");
+constexpr const ImmutableString texelFetchOffset_0X2C0C1C("texelFetchOffset(0X2C0C1C");
+constexpr const ImmutableString texelFetch_0H1C0C("texelFetch(0H1C0C");
+constexpr const ImmutableString texelFetch_0I2C0C("texelFetch(0I2C0C");
+constexpr const ImmutableString texelFetch_0K2C0C("texelFetch(0K2C0C");
+constexpr const ImmutableString texelFetch_0L1C0C("texelFetch(0L1C0C");
+constexpr const ImmutableString texelFetch_0O1C0C("texelFetch(0O1C0C");
+constexpr const ImmutableString texelFetch_0T1C0C("texelFetch(0T1C0C");
+constexpr const ImmutableString texelFetch_0V2C0C("texelFetch(0V2C0C");
+constexpr const ImmutableString texelFetch_0X2C0C("texelFetch(0X2C0C");
+constexpr const ImmutableString texture("texture");
+constexpr const ImmutableString texture2D("texture2D");
+constexpr const ImmutableString texture2DGradEXT("texture2DGradEXT");
+constexpr const ImmutableString texture2DGradEXT_0H1B1B1B("texture2DGradEXT(0H1B1B1B");
+constexpr const ImmutableString texture2DLod("texture2DLod");
+constexpr const ImmutableString texture2DLodEXT("texture2DLodEXT");
+constexpr const ImmutableString texture2DProj("texture2DProj");
+constexpr const ImmutableString texture2DProjGradEXT("texture2DProjGradEXT");
+constexpr const ImmutableString texture2DProjGradEXT_0H2B1B1B("texture2DProjGradEXT(0H2B1B1B");
+constexpr const ImmutableString texture2DProjGradEXT_0H3B1B1B("texture2DProjGradEXT(0H3B1B1B");
+constexpr const ImmutableString texture2DProjLod("texture2DProjLod");
+constexpr const ImmutableString texture2DProjLodEXT("texture2DProjLodEXT");
+constexpr const ImmutableString texture2DProjLod_0H2B0B("texture2DProjLod(0H2B0B");
+constexpr const ImmutableString texture2DProj_0H2B0B("texture2DProj(0H2B0B");
+constexpr const ImmutableString texture2DRect("texture2DRect");
+constexpr const ImmutableString texture2DRectProj("texture2DRectProj");
+constexpr const ImmutableString textureCube("textureCube");
+constexpr const ImmutableString textureCubeGradEXT("textureCubeGradEXT");
+constexpr const ImmutableString textureCubeGradEXT_0J2B2B2B("textureCubeGradEXT(0J2B2B2B");
+constexpr const ImmutableString textureCubeLod("textureCubeLod");
+constexpr const ImmutableString textureCubeLodEXT("textureCubeLodEXT");
+constexpr const ImmutableString textureGather("textureGather");
+constexpr const ImmutableString textureGatherOffset("textureGatherOffset");
+constexpr const ImmutableString textureGatherOffset_0H1B1C0C("textureGatherOffset(0H1B1C0C");
+constexpr const ImmutableString textureGatherOffset_0K2B1C0C("textureGatherOffset(0K2B1C0C");
+constexpr const ImmutableString textureGatherOffset_0P1B1C0C("textureGatherOffset(0P1B1C0C");
+constexpr const ImmutableString textureGatherOffset_0S2B1C0C("textureGatherOffset(0S2B1C0C");
+constexpr const ImmutableString textureGatherOffset_0U1B1C("textureGatherOffset(0U1B1C");
+constexpr const ImmutableString textureGatherOffset_0U1B1C0C("textureGatherOffset(0U1B1C0C");
+constexpr const ImmutableString textureGatherOffset_0X2B1C0C("textureGatherOffset(0X2B1C0C");
+constexpr const ImmutableString textureGatherOffset_0Z1B0B1C("textureGatherOffset(0Z1B0B1C");
+constexpr const ImmutableString textureGatherOffset_0b2B0B1C("textureGatherOffset(0b2B0B1C");
+constexpr const ImmutableString textureGather_0J2B0C("textureGather(0J2B0C");
+constexpr const ImmutableString textureGather_0P1B0C("textureGather(0P1B0C");
+constexpr const ImmutableString textureGather_0R2B0C("textureGather(0R2B0C");
+constexpr const ImmutableString textureGather_0a2B0B("textureGather(0a2B0B");
+constexpr const ImmutableString textureGrad("textureGrad");
+constexpr const ImmutableString textureGradOffset("textureGradOffset");
+constexpr const ImmutableString textureGradOffset_0H1B1B1B1C("textureGradOffset(0H1B1B1B1C");
+constexpr const ImmutableString textureGradOffset_0I2B2B2B2C("textureGradOffset(0I2B2B2B2C");
+constexpr const ImmutableString textureGradOffset_0K2B1B1B1C("textureGradOffset(0K2B1B1B1C");
+constexpr const ImmutableString textureGradOffset_0P1B1B1B1C("textureGradOffset(0P1B1B1B1C");
+constexpr const ImmutableString textureGradOffset_0Q2B2B2B2C("textureGradOffset(0Q2B2B2B2C");
+constexpr const ImmutableString textureGradOffset_0S2B1B1B1C("textureGradOffset(0S2B1B1B1C");
+constexpr const ImmutableString textureGradOffset_0U1B1B1B1C("textureGradOffset(0U1B1B1B1C");
+constexpr const ImmutableString textureGradOffset_0V2B2B2B2C("textureGradOffset(0V2B2B2B2C");
+constexpr const ImmutableString textureGradOffset_0X2B1B1B1C("textureGradOffset(0X2B1B1B1C");
+constexpr const ImmutableString textureGradOffset_0Z2B1B1B1C("textureGradOffset(0Z2B1B1B1C");
+constexpr const ImmutableString textureGradOffset_0b3B1B1B1C("textureGradOffset(0b3B1B1B1C");
+constexpr const ImmutableString textureGrad_0H1B1B1B("textureGrad(0H1B1B1B");
+constexpr const ImmutableString textureGrad_0I2B2B2B("textureGrad(0I2B2B2B");
+constexpr const ImmutableString textureGrad_0J2B2B2B("textureGrad(0J2B2B2B");
+constexpr const ImmutableString textureGrad_0K2B1B1B("textureGrad(0K2B1B1B");
+constexpr const ImmutableString textureGrad_0P1B1B1B("textureGrad(0P1B1B1B");
+constexpr const ImmutableString textureGrad_0Q2B2B2B("textureGrad(0Q2B2B2B");
+constexpr const ImmutableString textureGrad_0R2B2B2B("textureGrad(0R2B2B2B");
+constexpr const ImmutableString textureGrad_0S2B1B1B("textureGrad(0S2B1B1B");
+constexpr const ImmutableString textureGrad_0U1B1B1B("textureGrad(0U1B1B1B");
+constexpr const ImmutableString textureGrad_0V2B2B2B("textureGrad(0V2B2B2B");
+constexpr const ImmutableString textureGrad_0W2B2B2B("textureGrad(0W2B2B2B");
+constexpr const ImmutableString textureGrad_0X2B1B1B("textureGrad(0X2B1B1B");
+constexpr const ImmutableString textureGrad_0Z2B1B1B("textureGrad(0Z2B1B1B");
+constexpr const ImmutableString textureGrad_0a3B2B2B("textureGrad(0a3B2B2B");
+constexpr const ImmutableString textureGrad_0b3B1B1B("textureGrad(0b3B1B1B");
+constexpr const ImmutableString textureLod("textureLod");
+constexpr const ImmutableString textureLodOffset("textureLodOffset");
+constexpr const ImmutableString textureLodOffset_0H1B0B1C("textureLodOffset(0H1B0B1C");
+constexpr const ImmutableString textureLodOffset_0I2B0B2C("textureLodOffset(0I2B0B2C");
+constexpr const ImmutableString textureLodOffset_0K2B0B1C("textureLodOffset(0K2B0B1C");
+constexpr const ImmutableString textureLodOffset_0P1B0B1C("textureLodOffset(0P1B0B1C");
+constexpr const ImmutableString textureLodOffset_0Q2B0B2C("textureLodOffset(0Q2B0B2C");
+constexpr const ImmutableString textureLodOffset_0S2B0B1C("textureLodOffset(0S2B0B1C");
+constexpr const ImmutableString textureLodOffset_0U1B0B1C("textureLodOffset(0U1B0B1C");
+constexpr const ImmutableString textureLodOffset_0V2B0B2C("textureLodOffset(0V2B0B2C");
+constexpr const ImmutableString textureLodOffset_0X2B0B1C("textureLodOffset(0X2B0B1C");
+constexpr const ImmutableString textureLodOffset_0Z2B0B1C("textureLodOffset(0Z2B0B1C");
+constexpr const ImmutableString textureLod_0J2B0B("textureLod(0J2B0B");
+constexpr const ImmutableString textureLod_0P1B0B("textureLod(0P1B0B");
+constexpr const ImmutableString textureLod_0S2B0B("textureLod(0S2B0B");
+constexpr const ImmutableString textureLod_0Z2B0B("textureLod(0Z2B0B");
+constexpr const ImmutableString textureOffset("textureOffset");
+constexpr const ImmutableString textureOffset_0H1B1C0B("textureOffset(0H1B1C0B");
+constexpr const ImmutableString textureOffset_0I2B2C0B("textureOffset(0I2B2C0B");
+constexpr const ImmutableString textureOffset_0K2B1C0B("textureOffset(0K2B1C0B");
+constexpr const ImmutableString textureOffset_0P1B1C("textureOffset(0P1B1C");
+constexpr const ImmutableString textureOffset_0P1B1C0B("textureOffset(0P1B1C0B");
+constexpr const ImmutableString textureOffset_0Q2B2C("textureOffset(0Q2B2C");
+constexpr const ImmutableString textureOffset_0Q2B2C0B("textureOffset(0Q2B2C0B");
+constexpr const ImmutableString textureOffset_0S2B1C("textureOffset(0S2B1C");
+constexpr const ImmutableString textureOffset_0S2B1C0B("textureOffset(0S2B1C0B");
+constexpr const ImmutableString textureOffset_0U1B1C0B("textureOffset(0U1B1C0B");
+constexpr const ImmutableString textureOffset_0V2B2C("textureOffset(0V2B2C");
+constexpr const ImmutableString textureOffset_0V2B2C0B("textureOffset(0V2B2C0B");
+constexpr const ImmutableString textureOffset_0X2B1C0B("textureOffset(0X2B1C0B");
+constexpr const ImmutableString textureOffset_0Z2B1C0B("textureOffset(0Z2B1C0B");
+constexpr const ImmutableString textureProj("textureProj");
+constexpr const ImmutableString textureProjGrad("textureProjGrad");
+constexpr const ImmutableString textureProjGradOffset("textureProjGradOffset");
+constexpr const ImmutableString textureProjGradOffset_0H2B1B1B1C(
+    "textureProjGradOffset(0H2B1B1B1C");
+constexpr const ImmutableString textureProjGradOffset_0H3B1B1B1C(
+    "textureProjGradOffset(0H3B1B1B1C");
+constexpr const ImmutableString textureProjGradOffset_0I3B2B2B2C(
+    "textureProjGradOffset(0I3B2B2B2C");
+constexpr const ImmutableString textureProjGradOffset_0P2B1B1B1C(
+    "textureProjGradOffset(0P2B1B1B1C");
+constexpr const ImmutableString textureProjGradOffset_0P3B1B1B1C(
+    "textureProjGradOffset(0P3B1B1B1C");
+constexpr const ImmutableString textureProjGradOffset_0Q3B2B2B2C(
+    "textureProjGradOffset(0Q3B2B2B2C");
+constexpr const ImmutableString textureProjGradOffset_0U2B1B1B1C(
+    "textureProjGradOffset(0U2B1B1B1C");
+constexpr const ImmutableString textureProjGradOffset_0U3B1B1B1C(
+    "textureProjGradOffset(0U3B1B1B1C");
+constexpr const ImmutableString textureProjGradOffset_0V3B2B2B2C(
+    "textureProjGradOffset(0V3B2B2B2C");
+constexpr const ImmutableString textureProjGradOffset_0Z3B1B1B1C(
+    "textureProjGradOffset(0Z3B1B1B1C");
+constexpr const ImmutableString textureProjGrad_0H2B1B1B("textureProjGrad(0H2B1B1B");
+constexpr const ImmutableString textureProjGrad_0H3B1B1B("textureProjGrad(0H3B1B1B");
+constexpr const ImmutableString textureProjGrad_0I3B2B2B("textureProjGrad(0I3B2B2B");
+constexpr const ImmutableString textureProjGrad_0P2B1B1B("textureProjGrad(0P2B1B1B");
+constexpr const ImmutableString textureProjGrad_0P3B1B1B("textureProjGrad(0P3B1B1B");
+constexpr const ImmutableString textureProjGrad_0Q3B2B2B("textureProjGrad(0Q3B2B2B");
+constexpr const ImmutableString textureProjGrad_0U2B1B1B("textureProjGrad(0U2B1B1B");
+constexpr const ImmutableString textureProjGrad_0U3B1B1B("textureProjGrad(0U3B1B1B");
+constexpr const ImmutableString textureProjGrad_0V3B2B2B("textureProjGrad(0V3B2B2B");
+constexpr const ImmutableString textureProjGrad_0Z3B1B1B("textureProjGrad(0Z3B1B1B");
+constexpr const ImmutableString textureProjLod("textureProjLod");
+constexpr const ImmutableString textureProjLodOffset("textureProjLodOffset");
+constexpr const ImmutableString textureProjLodOffset_0H2B0B1C("textureProjLodOffset(0H2B0B1C");
+constexpr const ImmutableString textureProjLodOffset_0H3B0B1C("textureProjLodOffset(0H3B0B1C");
+constexpr const ImmutableString textureProjLodOffset_0I3B0B2C("textureProjLodOffset(0I3B0B2C");
+constexpr const ImmutableString textureProjLodOffset_0P2B0B1C("textureProjLodOffset(0P2B0B1C");
+constexpr const ImmutableString textureProjLodOffset_0P3B0B1C("textureProjLodOffset(0P3B0B1C");
+constexpr const ImmutableString textureProjLodOffset_0Q3B0B2C("textureProjLodOffset(0Q3B0B2C");
+constexpr const ImmutableString textureProjLodOffset_0U2B0B1C("textureProjLodOffset(0U2B0B1C");
+constexpr const ImmutableString textureProjLodOffset_0U3B0B1C("textureProjLodOffset(0U3B0B1C");
+constexpr const ImmutableString textureProjLodOffset_0V3B0B2C("textureProjLodOffset(0V3B0B2C");
+constexpr const ImmutableString textureProjLodOffset_0Z3B0B1C("textureProjLodOffset(0Z3B0B1C");
+constexpr const ImmutableString textureProjLod_0H3B0B("textureProjLod(0H3B0B");
+constexpr const ImmutableString textureProjLod_0Q3B0B("textureProjLod(0Q3B0B");
+constexpr const ImmutableString textureProjLod_0V3B0B("textureProjLod(0V3B0B");
+constexpr const ImmutableString textureProjLod_0Z3B0B("textureProjLod(0Z3B0B");
+constexpr const ImmutableString textureProjOffset("textureProjOffset");
+constexpr const ImmutableString textureProjOffset_0H2B1C("textureProjOffset(0H2B1C");
+constexpr const ImmutableString textureProjOffset_0H2B1C0B("textureProjOffset(0H2B1C0B");
+constexpr const ImmutableString textureProjOffset_0H3B1C("textureProjOffset(0H3B1C");
+constexpr const ImmutableString textureProjOffset_0H3B1C0B("textureProjOffset(0H3B1C0B");
+constexpr const ImmutableString textureProjOffset_0I3B2C0B("textureProjOffset(0I3B2C0B");
+constexpr const ImmutableString textureProjOffset_0P2B1C0B("textureProjOffset(0P2B1C0B");
+constexpr const ImmutableString textureProjOffset_0P3B1C0B("textureProjOffset(0P3B1C0B");
+constexpr const ImmutableString textureProjOffset_0Q3B2C("textureProjOffset(0Q3B2C");
+constexpr const ImmutableString textureProjOffset_0Q3B2C0B("textureProjOffset(0Q3B2C0B");
+constexpr const ImmutableString textureProjOffset_0U2B1C("textureProjOffset(0U2B1C");
+constexpr const ImmutableString textureProjOffset_0U2B1C0B("textureProjOffset(0U2B1C0B");
+constexpr const ImmutableString textureProjOffset_0U3B1C0B("textureProjOffset(0U3B1C0B");
+constexpr const ImmutableString textureProjOffset_0V3B2C("textureProjOffset(0V3B2C");
+constexpr const ImmutableString textureProjOffset_0V3B2C0B("textureProjOffset(0V3B2C0B");
+constexpr const ImmutableString textureProjOffset_0Z3B1C0B("textureProjOffset(0Z3B1C0B");
+constexpr const ImmutableString textureSize("textureSize");
+constexpr const ImmutableString texture_0V2B0B("texture(0V2B0B");
+constexpr const ImmutableString texture_0W2B0B("texture(0W2B0B");
+constexpr const ImmutableString transpose("transpose");
+constexpr const ImmutableString trunc("trunc");
+constexpr const ImmutableString uaddCarry("uaddCarry");
+constexpr const ImmutableString uaddCarry_2D2D2D("uaddCarry(2D2D2D");
+constexpr const ImmutableString uaddCarry_3D3D3D("uaddCarry(3D3D3D");
+constexpr const ImmutableString uintBitsToFloat("uintBitsToFloat");
+constexpr const ImmutableString umulExtended("umulExtended");
+constexpr const ImmutableString umulExtended_0D0D0D0D("umulExtended(0D0D0D0D");
+constexpr const ImmutableString umulExtended_1D1D1D1D("umulExtended(1D1D1D1D");
+constexpr const ImmutableString umulExtended_2D2D2D2D("umulExtended(2D2D2D2D");
+constexpr const ImmutableString umulExtended_3D3D3D3D("umulExtended(3D3D3D3D");
+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 usubBorrow_0D0D0D("usubBorrow(0D0D0D");
+constexpr const ImmutableString usubBorrow_1D1D1D("usubBorrow(1D1D1D");
+constexpr const ImmutableString usubBorrow_3D3D3D("usubBorrow(3D3D3D");
+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 TVariable kVar_gl_FragColor(
+    BuiltInId::gl_FragColor,
+    BuiltInName::gl_FragColor,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtFloat, EbpMedium, EvqFragColor, 4, 1>());
+constexpr const TVariable kVar_gl_FragCoord(
+    BuiltInId::gl_FragCoord,
+    BuiltInName::gl_FragCoord,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtFloat, EbpMedium, EvqFragCoord, 4, 1>());
+constexpr const TVariable kVar_gl_FragDepth(
+    BuiltInId::gl_FragDepth,
+    BuiltInName::gl_FragDepth,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtFloat, EbpHigh, EvqFragDepth, 1, 1>());
+constexpr const TVariable kVar_gl_FrontFacing(
+    BuiltInId::gl_FrontFacing,
+    BuiltInName::gl_FrontFacing,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtBool, EbpUndefined, EvqFrontFacing, 1, 1>());
+constexpr const TVariable kVar_gl_GlobalInvocationID(
+    BuiltInId::gl_GlobalInvocationID,
+    BuiltInName::gl_GlobalInvocationID,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobalInvocationID, 3, 1>());
+constexpr const TVariable kVar_gl_InstanceID(
+    BuiltInId::gl_InstanceID,
+    BuiltInName::gl_InstanceID,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtInt, EbpHigh, EvqInstanceID, 1, 1>());
+constexpr const TVariable kVar_gl_InvocationID(
+    BuiltInId::gl_InvocationID,
+    BuiltInName::gl_InvocationID,
+    SymbolType::BuiltIn,
+    TExtension::EXT_geometry_shader,
+    StaticType::Get<EbtInt, EbpHigh, EvqInvocationID, 1, 1>());
+constexpr const TVariable kVar_gl_LastFragColor(
+    BuiltInId::gl_LastFragColor,
+    BuiltInName::gl_LastFragColor,
+    SymbolType::BuiltIn,
+    TExtension::NV_shader_framebuffer_fetch,
+    StaticType::Get<EbtFloat, EbpMedium, EvqLastFragColor, 4, 1>());
+constexpr const TVariable kVar_gl_LastFragColorARM(
+    BuiltInId::gl_LastFragColorARM,
+    BuiltInName::gl_LastFragColorARM,
+    SymbolType::BuiltIn,
+    TExtension::ARM_shader_framebuffer_fetch,
+    StaticType::Get<EbtFloat, EbpMedium, EvqLastFragColor, 4, 1>());
+constexpr const TVariable kVar_gl_Layer(BuiltInId::gl_Layer,
+                                        BuiltInName::gl_Layer,
+                                        SymbolType::BuiltIn,
+                                        TExtension::EXT_geometry_shader,
+                                        StaticType::Get<EbtInt, EbpHigh, EvqLayer, 1, 1>());
+constexpr const TVariable kVar_gl_LayerGS(BuiltInId::gl_LayerGS,
+                                          BuiltInName::gl_Layer,
+                                          SymbolType::BuiltIn,
+                                          TExtension::EXT_geometry_shader,
+                                          StaticType::Get<EbtInt, EbpHigh, EvqLayer, 1, 1>());
+constexpr const TVariable kVar_gl_LayerVS(BuiltInId::gl_LayerVS,
+                                          BuiltInName::gl_Layer,
+                                          SymbolType::BuiltIn,
+                                          TExtension::UNDEFINED,
+                                          StaticType::Get<EbtInt, EbpHigh, EvqLayer, 1, 1>());
+constexpr const TVariable kVar_gl_LocalInvocationID(
+    BuiltInId::gl_LocalInvocationID,
+    BuiltInName::gl_LocalInvocationID,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqLocalInvocationID, 3, 1>());
+constexpr const TVariable kVar_gl_LocalInvocationIndex(
+    BuiltInId::gl_LocalInvocationIndex,
+    BuiltInName::gl_LocalInvocationIndex,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqLocalInvocationIndex, 1, 1>());
+constexpr const TVariable kVar_gl_NumWorkGroups(
+    BuiltInId::gl_NumWorkGroups,
+    BuiltInName::gl_NumWorkGroups,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqNumWorkGroups, 3, 1>());
+constexpr const TVariable kVar_gl_PointCoord(
+    BuiltInId::gl_PointCoord,
+    BuiltInName::gl_PointCoord,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtFloat, EbpMedium, EvqPointCoord, 2, 1>());
+constexpr const TVariable kVar_gl_PointSize(
+    BuiltInId::gl_PointSize,
+    BuiltInName::gl_PointSize,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtFloat, EbpMedium, EvqPointSize, 1, 1>());
+constexpr const TVariable kVar_gl_Position(BuiltInId::gl_Position,
+                                           BuiltInName::gl_Position,
+                                           SymbolType::BuiltIn,
+                                           TExtension::UNDEFINED,
+                                           StaticType::Get<EbtFloat, EbpHigh, EvqPosition, 4, 1>());
+constexpr const TVariable kVar_gl_PrimitiveID(
+    BuiltInId::gl_PrimitiveID,
+    BuiltInName::gl_PrimitiveID,
+    SymbolType::BuiltIn,
+    TExtension::EXT_geometry_shader,
+    StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kVar_gl_PrimitiveIDGS(
+    BuiltInId::gl_PrimitiveIDGS,
+    BuiltInName::gl_PrimitiveID,
+    SymbolType::BuiltIn,
+    TExtension::EXT_geometry_shader,
+    StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kVar_gl_PrimitiveIDIn(
+    BuiltInId::gl_PrimitiveIDIn,
+    BuiltInName::gl_PrimitiveIDIn,
+    SymbolType::BuiltIn,
+    TExtension::EXT_geometry_shader,
+    StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveIDIn, 1, 1>());
+constexpr const TVariable kVar_gl_SecondaryFragColorEXT(
+    BuiltInId::gl_SecondaryFragColorEXT,
+    BuiltInName::gl_SecondaryFragColorEXT,
+    SymbolType::BuiltIn,
+    TExtension::EXT_blend_func_extended,
+    StaticType::Get<EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4, 1>());
+constexpr const TVariable kVar_gl_VertexID(BuiltInId::gl_VertexID,
+                                           BuiltInName::gl_VertexID,
+                                           SymbolType::BuiltIn,
+                                           TExtension::UNDEFINED,
+                                           StaticType::Get<EbtInt, EbpHigh, EvqVertexID, 1, 1>());
+constexpr const TVariable kVar_gl_ViewID_OVR(
+    BuiltInId::gl_ViewID_OVR,
+    BuiltInName::gl_ViewID_OVR,
+    SymbolType::BuiltIn,
+    TExtension::OVR_multiview,
+    StaticType::Get<EbtUInt, EbpHigh, EvqViewIDOVR, 1, 1>());
+constexpr const TVariable kVar_gl_ViewID_OVRESSL1(
+    BuiltInId::gl_ViewID_OVRESSL1,
+    BuiltInName::gl_ViewID_OVR,
+    SymbolType::BuiltIn,
+    TExtension::OVR_multiview,
+    StaticType::Get<EbtInt, EbpHigh, EvqViewIDOVR, 1, 1>());
+constexpr const TVariable kVar_gl_ViewportIndex(
+    BuiltInId::gl_ViewportIndex,
+    BuiltInName::gl_ViewportIndex,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtInt, EbpHigh, EvqViewportIndex, 1, 1>());
+constexpr const TVariable kVar_gl_WorkGroupID(
+    BuiltInId::gl_WorkGroupID,
+    BuiltInName::gl_WorkGroupID,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqWorkGroupID, 3, 1>());
+constexpr const TVariable kVar_gl_WorkGroupSize(
+    BuiltInId::gl_WorkGroupSize,
+    BuiltInName::gl_WorkGroupSize,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqWorkGroupSize, 3, 1>());
+constexpr const TVariable kVar_pt0B(BuiltInId::pt0B,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0C(BuiltInId::pt0C,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0D(BuiltInId::pt0D,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0E(BuiltInId::pt0E,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0F(
+    BuiltInId::pt0F,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtAtomicCounter, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0G(
+    BuiltInId::pt0G,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtYuvCscStandardEXT, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0H(BuiltInId::pt0H,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtSampler2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0I(BuiltInId::pt0I,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtSampler3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0J(
+    BuiltInId::pt0J,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtSamplerCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0K(
+    BuiltInId::pt0K,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtSampler2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0L(
+    BuiltInId::pt0L,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtSamplerExternalOES, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0M(
+    BuiltInId::pt0M,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtSamplerExternal2DY2YEXT, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0N(
+    BuiltInId::pt0N,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtSampler2DRect, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0O(
+    BuiltInId::pt0O,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtSampler2DMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0P(
+    BuiltInId::pt0P,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtISampler2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0Q(
+    BuiltInId::pt0Q,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtISampler3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0R(
+    BuiltInId::pt0R,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtISamplerCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0S(
+    BuiltInId::pt0S,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtISampler2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0T(
+    BuiltInId::pt0T,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtISampler2DMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0U(
+    BuiltInId::pt0U,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtUSampler2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0V(
+    BuiltInId::pt0V,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtUSampler3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0W(
+    BuiltInId::pt0W,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtUSamplerCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0X(
+    BuiltInId::pt0X,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtUSampler2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0Y(
+    BuiltInId::pt0Y,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtUSampler2DMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0Z(
+    BuiltInId::pt0Z,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtSampler2DShadow, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0a(
+    BuiltInId::pt0a,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtSamplerCubeShadow, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0b(
+    BuiltInId::pt0b,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtSampler2DArrayShadow, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0c(BuiltInId::pt0c,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtImage2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0d(BuiltInId::pt0d,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtIImage2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0e(BuiltInId::pt0e,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtUImage2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0f(BuiltInId::pt0f,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtImage3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0g(BuiltInId::pt0g,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtIImage3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0h(BuiltInId::pt0h,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtUImage3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0i(
+    BuiltInId::pt0i,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtImage2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0j(
+    BuiltInId::pt0j,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtIImage2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0k(
+    BuiltInId::pt0k,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtUImage2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0l(BuiltInId::pt0l,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtImageCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0m(
+    BuiltInId::pt0m,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtIImageCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt0n(
+    BuiltInId::pt0n,
+    BuiltInName::_empty,
+    SymbolType::BuiltIn,
+    TExtension::UNDEFINED,
+    StaticType::Get<EbtUImageCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kVar_pt1B(BuiltInId::pt1B,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>());
+constexpr const TVariable kVar_pt1C(BuiltInId::pt1C,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>());
+constexpr const TVariable kVar_pt1D(BuiltInId::pt1D,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>());
+constexpr const TVariable kVar_pt1E(BuiltInId::pt1E,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>());
+constexpr const TVariable kVar_pt2B(BuiltInId::pt2B,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>());
+constexpr const TVariable kVar_pt2C(BuiltInId::pt2C,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>());
+constexpr const TVariable kVar_pt2D(BuiltInId::pt2D,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>());
+constexpr const TVariable kVar_pt2E(BuiltInId::pt2E,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>());
+constexpr const TVariable kVar_pt3B(BuiltInId::pt3B,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>());
+constexpr const TVariable kVar_pt3C(BuiltInId::pt3C,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>());
+constexpr const TVariable kVar_pt3D(BuiltInId::pt3D,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>());
+constexpr const TVariable kVar_pt3E(BuiltInId::pt3E,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>());
+constexpr const TVariable kVar_pt5B(BuiltInId::pt5B,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 2>());
+constexpr const TVariable kVar_pt6B(BuiltInId::pt6B,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 2>());
+constexpr const TVariable kVar_pt7B(BuiltInId::pt7B,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 2>());
+constexpr const TVariable kVar_pt9B(BuiltInId::pt9B,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 3>());
+constexpr const TVariable kVar_ptAB(BuiltInId::ptAB,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 3>());
+constexpr const TVariable kVar_ptBB(BuiltInId::ptBB,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 3>());
+constexpr const TVariable kVar_ptDB(BuiltInId::ptDB,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 4>());
+constexpr const TVariable kVar_ptEB(BuiltInId::ptEB,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 4>());
+constexpr const TVariable kVar_ptFB(BuiltInId::ptFB,
+                                    BuiltInName::_empty,
+                                    SymbolType::BuiltIn,
+                                    TExtension::UNDEFINED,
+                                    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 4>());
+constexpr const TVariable kVar_pt_io_0C(BuiltInId::pt_io_0C,
+                                        BuiltInName::_empty,
+                                        SymbolType::BuiltIn,
+                                        TExtension::UNDEFINED,
+                                        StaticType::Get<EbtInt, EbpUndefined, EvqInOut, 1, 1>());
+constexpr const TVariable kVar_pt_io_0D(BuiltInId::pt_io_0D,
+                                        BuiltInName::_empty,
+                                        SymbolType::BuiltIn,
+                                        TExtension::UNDEFINED,
+                                        StaticType::Get<EbtUInt, EbpUndefined, EvqInOut, 1, 1>());
+constexpr const TVariable kVar_pt_o_0B(BuiltInId::pt_o_0B,
+                                       BuiltInName::_empty,
+                                       SymbolType::BuiltIn,
+                                       TExtension::UNDEFINED,
+                                       StaticType::Get<EbtFloat, EbpUndefined, EvqOut, 1, 1>());
+constexpr const TVariable kVar_pt_o_0C(BuiltInId::pt_o_0C,
+                                       BuiltInName::_empty,
+                                       SymbolType::BuiltIn,
+                                       TExtension::UNDEFINED,
+                                       StaticType::Get<EbtInt, EbpUndefined, EvqOut, 1, 1>());
+constexpr const TVariable kVar_pt_o_0D(BuiltInId::pt_o_0D,
+                                       BuiltInName::_empty,
+                                       SymbolType::BuiltIn,
+                                       TExtension::UNDEFINED,
+                                       StaticType::Get<EbtUInt, EbpUndefined, EvqOut, 1, 1>());
+constexpr const TVariable kVar_pt_o_1B(BuiltInId::pt_o_1B,
+                                       BuiltInName::_empty,
+                                       SymbolType::BuiltIn,
+                                       TExtension::UNDEFINED,
+                                       StaticType::Get<EbtFloat, EbpUndefined, EvqOut, 2, 1>());
+constexpr const TVariable kVar_pt_o_1C(BuiltInId::pt_o_1C,
+                                       BuiltInName::_empty,
+                                       SymbolType::BuiltIn,
+                                       TExtension::UNDEFINED,
+                                       StaticType::Get<EbtInt, EbpUndefined, EvqOut, 2, 1>());
+constexpr const TVariable kVar_pt_o_1D(BuiltInId::pt_o_1D,
+                                       BuiltInName::_empty,
+                                       SymbolType::BuiltIn,
+                                       TExtension::UNDEFINED,
+                                       StaticType::Get<EbtUInt, EbpUndefined, EvqOut, 2, 1>());
+constexpr const TVariable kVar_pt_o_2B(BuiltInId::pt_o_2B,
+                                       BuiltInName::_empty,
+                                       SymbolType::BuiltIn,
+                                       TExtension::UNDEFINED,
+                                       StaticType::Get<EbtFloat, EbpUndefined, EvqOut, 3, 1>());
+constexpr const TVariable kVar_pt_o_2C(BuiltInId::pt_o_2C,
+                                       BuiltInName::_empty,
+                                       SymbolType::BuiltIn,
+                                       TExtension::UNDEFINED,
+                                       StaticType::Get<EbtInt, EbpUndefined, EvqOut, 3, 1>());
+constexpr const TVariable kVar_pt_o_2D(BuiltInId::pt_o_2D,
+                                       BuiltInName::_empty,
+                                       SymbolType::BuiltIn,
+                                       TExtension::UNDEFINED,
+                                       StaticType::Get<EbtUInt, EbpUndefined, EvqOut, 3, 1>());
+constexpr const TVariable kVar_pt_o_3B(BuiltInId::pt_o_3B,
+                                       BuiltInName::_empty,
+                                       SymbolType::BuiltIn,
+                                       TExtension::UNDEFINED,
+                                       StaticType::Get<EbtFloat, EbpUndefined, EvqOut, 4, 1>());
+constexpr const TVariable kVar_pt_o_3C(BuiltInId::pt_o_3C,
+                                       BuiltInName::_empty,
+                                       SymbolType::BuiltIn,
+                                       TExtension::UNDEFINED,
+                                       StaticType::Get<EbtInt, EbpUndefined, EvqOut, 4, 1>());
+constexpr const TVariable kVar_pt_o_3D(BuiltInId::pt_o_3D,
+                                       BuiltInName::_empty,
+                                       SymbolType::BuiltIn,
+                                       TExtension::UNDEFINED,
+                                       StaticType::Get<EbtUInt, EbpUndefined, EvqOut, 4, 1>());
+
+const TVariable *gl_FragColor()
+{
+    return &kVar_gl_FragColor;
+}
+
+const TVariable *gl_FragCoord()
+{
+    return &kVar_gl_FragCoord;
+}
+
+const TVariable *gl_FragDepth()
+{
+    return &kVar_gl_FragDepth;
+}
+
+const TVariable *gl_FrontFacing()
+{
+    return &kVar_gl_FrontFacing;
+}
+
+const TVariable *gl_GlobalInvocationID()
+{
+    return &kVar_gl_GlobalInvocationID;
+}
+
+const TVariable *gl_InstanceID()
+{
+    return &kVar_gl_InstanceID;
+}
+
+const TVariable *gl_InvocationID()
+{
+    return &kVar_gl_InvocationID;
+}
+
+const TVariable *gl_LastFragColor()
+{
+    return &kVar_gl_LastFragColor;
+}
+
+const TVariable *gl_LastFragColorARM()
+{
+    return &kVar_gl_LastFragColorARM;
+}
+
+const TVariable *gl_Layer()
+{
+    return &kVar_gl_Layer;
+}
+
+const TVariable *gl_LayerGS()
+{
+    return &kVar_gl_LayerGS;
+}
+
+const TVariable *gl_LayerVS()
+{
+    return &kVar_gl_LayerVS;
+}
+
+const TVariable *gl_LocalInvocationID()
+{
+    return &kVar_gl_LocalInvocationID;
+}
+
+const TVariable *gl_LocalInvocationIndex()
+{
+    return &kVar_gl_LocalInvocationIndex;
+}
+
+const TVariable *gl_NumWorkGroups()
+{
+    return &kVar_gl_NumWorkGroups;
+}
+
+const TVariable *gl_PointCoord()
+{
+    return &kVar_gl_PointCoord;
+}
+
+const TVariable *gl_PointSize()
+{
+    return &kVar_gl_PointSize;
+}
+
+const TVariable *gl_Position()
+{
+    return &kVar_gl_Position;
+}
+
+const TVariable *gl_PrimitiveID()
+{
+    return &kVar_gl_PrimitiveID;
+}
+
+const TVariable *gl_PrimitiveIDGS()
+{
+    return &kVar_gl_PrimitiveIDGS;
+}
+
+const TVariable *gl_PrimitiveIDIn()
+{
+    return &kVar_gl_PrimitiveIDIn;
+}
+
+const TVariable *gl_SecondaryFragColorEXT()
+{
+    return &kVar_gl_SecondaryFragColorEXT;
+}
+
+const TVariable *gl_VertexID()
+{
+    return &kVar_gl_VertexID;
+}
+
+const TVariable *gl_ViewID_OVR()
+{
+    return &kVar_gl_ViewID_OVR;
+}
+
+const TVariable *gl_ViewID_OVRESSL1()
+{
+    return &kVar_gl_ViewID_OVRESSL1;
+}
+
+const TVariable *gl_ViewportIndex()
+{
+    return &kVar_gl_ViewportIndex;
+}
+
+const TVariable *gl_WorkGroupID()
+{
+    return &kVar_gl_WorkGroupID;
+}
+
+const TVariable *gl_WorkGroupSize()
+{
+    return &kVar_gl_WorkGroupSize;
+}
+
+};  // namespace BuiltInVariable
+
+namespace BuiltInParameters
+{
+
+constexpr const TVariable **empty      = nullptr;
+constexpr const TVariable *p0B0B0B[3]  = {&BuiltInVariable::kVar_pt0B, &BuiltInVariable::kVar_pt0B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0B0B0E[3]  = {&BuiltInVariable::kVar_pt0B, &BuiltInVariable::kVar_pt0B,
+                                         &BuiltInVariable::kVar_pt0E};
+constexpr const TVariable *p0B0B1B[3]  = {&BuiltInVariable::kVar_pt0B, &BuiltInVariable::kVar_pt0B,
+                                         &BuiltInVariable::kVar_pt1B};
+constexpr const TVariable *p0B0B2B[3]  = {&BuiltInVariable::kVar_pt0B, &BuiltInVariable::kVar_pt0B,
+                                         &BuiltInVariable::kVar_pt2B};
+constexpr const TVariable *p0B0B3B[3]  = {&BuiltInVariable::kVar_pt0B, &BuiltInVariable::kVar_pt0B,
+                                         &BuiltInVariable::kVar_pt3B};
+constexpr const TVariable *p0B0C[2]    = {&BuiltInVariable::kVar_pt0B, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0B1B[2]    = {&BuiltInVariable::kVar_pt0B, &BuiltInVariable::kVar_pt1B};
+constexpr const TVariable *p0B2B[2]    = {&BuiltInVariable::kVar_pt0B, &BuiltInVariable::kVar_pt2B};
+constexpr const TVariable *p0B3B[2]    = {&BuiltInVariable::kVar_pt0B, &BuiltInVariable::kVar_pt3B};
+constexpr const TVariable *p0B_o_0B[2] = {&BuiltInVariable::kVar_pt0B,
+                                          &BuiltInVariable::kVar_pt_o_0B};
+constexpr const TVariable *p0B_o_0C[2] = {&BuiltInVariable::kVar_pt0B,
+                                          &BuiltInVariable::kVar_pt_o_0C};
+constexpr const TVariable *p0C0C0C0C[4] = {&BuiltInVariable::kVar_pt0C, &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0C0C_o_0C_o_0C[4] = {
+    &BuiltInVariable::kVar_pt0C, &BuiltInVariable::kVar_pt0C, &BuiltInVariable::kVar_pt_o_0C,
+    &BuiltInVariable::kVar_pt_o_0C};
+constexpr const TVariable *p0D0C0C[3]   = {&BuiltInVariable::kVar_pt0D, &BuiltInVariable::kVar_pt0C,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0D0D0C0C[4] = {&BuiltInVariable::kVar_pt0D, &BuiltInVariable::kVar_pt0D,
+                                           &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0D0D0D[3]   = {&BuiltInVariable::kVar_pt0D, &BuiltInVariable::kVar_pt0D,
+                                         &BuiltInVariable::kVar_pt0D};
+constexpr const TVariable *p0D0D_o_0D_o_0D[4] = {
+    &BuiltInVariable::kVar_pt0D, &BuiltInVariable::kVar_pt0D, &BuiltInVariable::kVar_pt_o_0D,
+    &BuiltInVariable::kVar_pt_o_0D};
+constexpr const TVariable *p0F[1]   = {&BuiltInVariable::kVar_pt0F};
+constexpr const TVariable *p0H0C[2] = {&BuiltInVariable::kVar_pt0H, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0H1B0B1C[4] = {&BuiltInVariable::kVar_pt0H, &BuiltInVariable::kVar_pt1B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0H1B0C[3]   = {&BuiltInVariable::kVar_pt0H, &BuiltInVariable::kVar_pt1B,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0H1B1B1B1C[5] = {
+    &BuiltInVariable::kVar_pt0H, &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1B,
+    &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0H1B1C0B[4] = {&BuiltInVariable::kVar_pt0H, &BuiltInVariable::kVar_pt1B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0H1B1C0C[4] = {&BuiltInVariable::kVar_pt0H, &BuiltInVariable::kVar_pt1B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0H1C0C1C[4] = {&BuiltInVariable::kVar_pt0H, &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0H2B0B1C[4] = {&BuiltInVariable::kVar_pt0H, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0H2B1B1B1C[5] = {
+    &BuiltInVariable::kVar_pt0H, &BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt1B,
+    &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0H2B1C0B[4] = {&BuiltInVariable::kVar_pt0H, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0H3B0B1C[4] = {&BuiltInVariable::kVar_pt0H, &BuiltInVariable::kVar_pt3B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0H3B1B1B1C[5] = {
+    &BuiltInVariable::kVar_pt0H, &BuiltInVariable::kVar_pt3B, &BuiltInVariable::kVar_pt1B,
+    &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0H3B1C0B[4] = {&BuiltInVariable::kVar_pt0H, &BuiltInVariable::kVar_pt3B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0I0C[2] = {&BuiltInVariable::kVar_pt0I, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0I2B0B2C[4] = {&BuiltInVariable::kVar_pt0I, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt2C};
+constexpr const TVariable *p0I2B2B2B2C[5] = {
+    &BuiltInVariable::kVar_pt0I, &BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt2B,
+    &BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt2C};
+constexpr const TVariable *p0I2B2C0B[4] = {&BuiltInVariable::kVar_pt0I, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt2C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0I2C0C2C[4] = {&BuiltInVariable::kVar_pt0I, &BuiltInVariable::kVar_pt2C,
+                                           &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt2C};
+constexpr const TVariable *p0I3B0B2C[4] = {&BuiltInVariable::kVar_pt0I, &BuiltInVariable::kVar_pt3B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt2C};
+constexpr const TVariable *p0I3B2B2B2C[5] = {
+    &BuiltInVariable::kVar_pt0I, &BuiltInVariable::kVar_pt3B, &BuiltInVariable::kVar_pt2B,
+    &BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt2C};
+constexpr const TVariable *p0I3B2C0B[4] = {&BuiltInVariable::kVar_pt0I, &BuiltInVariable::kVar_pt3B,
+                                           &BuiltInVariable::kVar_pt2C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0J0C[2]   = {&BuiltInVariable::kVar_pt0J, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0J2B0B[3] = {&BuiltInVariable::kVar_pt0J, &BuiltInVariable::kVar_pt2B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0J2B0C[3] = {&BuiltInVariable::kVar_pt0J, &BuiltInVariable::kVar_pt2B,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0J2B2B2B[4] = {&BuiltInVariable::kVar_pt0J, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt2B};
+constexpr const TVariable *p0K0C[2] = {&BuiltInVariable::kVar_pt0K, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0K2B0B1C[4] = {&BuiltInVariable::kVar_pt0K, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0K2B0C[3]   = {&BuiltInVariable::kVar_pt0K, &BuiltInVariable::kVar_pt2B,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0K2B1B1B1C[5] = {
+    &BuiltInVariable::kVar_pt0K, &BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt1B,
+    &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0K2B1C0B[4] = {&BuiltInVariable::kVar_pt0K, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0K2B1C0C[4] = {&BuiltInVariable::kVar_pt0K, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0K2C0C1C[4] = {&BuiltInVariable::kVar_pt0K, &BuiltInVariable::kVar_pt2C,
+                                           &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0L0C[2]   = {&BuiltInVariable::kVar_pt0L, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0L1B0B[3] = {&BuiltInVariable::kVar_pt0L, &BuiltInVariable::kVar_pt1B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0L1C0C[3] = {&BuiltInVariable::kVar_pt0L, &BuiltInVariable::kVar_pt1C,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0L2B0B[3] = {&BuiltInVariable::kVar_pt0L, &BuiltInVariable::kVar_pt2B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0L3B0B[3] = {&BuiltInVariable::kVar_pt0L, &BuiltInVariable::kVar_pt3B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0M0C[2]   = {&BuiltInVariable::kVar_pt0M, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0M1B0B[3] = {&BuiltInVariable::kVar_pt0M, &BuiltInVariable::kVar_pt1B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0M1C0C[3] = {&BuiltInVariable::kVar_pt0M, &BuiltInVariable::kVar_pt1C,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0M2B0B[3] = {&BuiltInVariable::kVar_pt0M, &BuiltInVariable::kVar_pt2B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0M3B0B[3] = {&BuiltInVariable::kVar_pt0M, &BuiltInVariable::kVar_pt3B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0N1B[2]   = {&BuiltInVariable::kVar_pt0N, &BuiltInVariable::kVar_pt1B};
+constexpr const TVariable *p0N2B[2]   = {&BuiltInVariable::kVar_pt0N, &BuiltInVariable::kVar_pt2B};
+constexpr const TVariable *p0N3B[2]   = {&BuiltInVariable::kVar_pt0N, &BuiltInVariable::kVar_pt3B};
+constexpr const TVariable *p0O1C0C[3] = {&BuiltInVariable::kVar_pt0O, &BuiltInVariable::kVar_pt1C,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0P0C[2]   = {&BuiltInVariable::kVar_pt0P, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0P1B0B1C[4] = {&BuiltInVariable::kVar_pt0P, &BuiltInVariable::kVar_pt1B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0P1B0C[3]   = {&BuiltInVariable::kVar_pt0P, &BuiltInVariable::kVar_pt1B,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0P1B1B1B1C[5] = {
+    &BuiltInVariable::kVar_pt0P, &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1B,
+    &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0P1B1C0B[4] = {&BuiltInVariable::kVar_pt0P, &BuiltInVariable::kVar_pt1B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0P1B1C0C[4] = {&BuiltInVariable::kVar_pt0P, &BuiltInVariable::kVar_pt1B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0P1C0C1C[4] = {&BuiltInVariable::kVar_pt0P, &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0P2B0B1C[4] = {&BuiltInVariable::kVar_pt0P, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0P2B1B1B1C[5] = {
+    &BuiltInVariable::kVar_pt0P, &BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt1B,
+    &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0P2B1C0B[4] = {&BuiltInVariable::kVar_pt0P, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0P3B0B1C[4] = {&BuiltInVariable::kVar_pt0P, &BuiltInVariable::kVar_pt3B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0P3B1B1B1C[5] = {
+    &BuiltInVariable::kVar_pt0P, &BuiltInVariable::kVar_pt3B, &BuiltInVariable::kVar_pt1B,
+    &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0P3B1C0B[4] = {&BuiltInVariable::kVar_pt0P, &BuiltInVariable::kVar_pt3B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0Q0C[2] = {&BuiltInVariable::kVar_pt0Q, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0Q2B0B2C[4] = {&BuiltInVariable::kVar_pt0Q, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt2C};
+constexpr const TVariable *p0Q2B2B2B2C[5] = {
+    &BuiltInVariable::kVar_pt0Q, &BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt2B,
+    &BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt2C};
+constexpr const TVariable *p0Q2B2C0B[4] = {&BuiltInVariable::kVar_pt0Q, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt2C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0Q2C0C2C[4] = {&BuiltInVariable::kVar_pt0Q, &BuiltInVariable::kVar_pt2C,
+                                           &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt2C};
+constexpr const TVariable *p0Q3B0B2C[4] = {&BuiltInVariable::kVar_pt0Q, &BuiltInVariable::kVar_pt3B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt2C};
+constexpr const TVariable *p0Q3B2B2B2C[5] = {
+    &BuiltInVariable::kVar_pt0Q, &BuiltInVariable::kVar_pt3B, &BuiltInVariable::kVar_pt2B,
+    &BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt2C};
+constexpr const TVariable *p0Q3B2C0B[4] = {&BuiltInVariable::kVar_pt0Q, &BuiltInVariable::kVar_pt3B,
+                                           &BuiltInVariable::kVar_pt2C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0R0C[2]   = {&BuiltInVariable::kVar_pt0R, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0R2B0B[3] = {&BuiltInVariable::kVar_pt0R, &BuiltInVariable::kVar_pt2B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0R2B0C[3] = {&BuiltInVariable::kVar_pt0R, &BuiltInVariable::kVar_pt2B,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0R2B2B2B[4] = {&BuiltInVariable::kVar_pt0R, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt2B};
+constexpr const TVariable *p0S0C[2] = {&BuiltInVariable::kVar_pt0S, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0S2B0B1C[4] = {&BuiltInVariable::kVar_pt0S, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0S2B0C[3]   = {&BuiltInVariable::kVar_pt0S, &BuiltInVariable::kVar_pt2B,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0S2B1B1B1C[5] = {
+    &BuiltInVariable::kVar_pt0S, &BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt1B,
+    &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0S2B1C0B[4] = {&BuiltInVariable::kVar_pt0S, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0S2B1C0C[4] = {&BuiltInVariable::kVar_pt0S, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0S2C0C1C[4] = {&BuiltInVariable::kVar_pt0S, &BuiltInVariable::kVar_pt2C,
+                                           &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0T1C0C[3]   = {&BuiltInVariable::kVar_pt0T, &BuiltInVariable::kVar_pt1C,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0U0C[2] = {&BuiltInVariable::kVar_pt0U, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0U1B0B1C[4] = {&BuiltInVariable::kVar_pt0U, &BuiltInVariable::kVar_pt1B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0U1B0C[3]   = {&BuiltInVariable::kVar_pt0U, &BuiltInVariable::kVar_pt1B,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0U1B1B1B1C[5] = {
+    &BuiltInVariable::kVar_pt0U, &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1B,
+    &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0U1B1C0B[4] = {&BuiltInVariable::kVar_pt0U, &BuiltInVariable::kVar_pt1B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0U1B1C0C[4] = {&BuiltInVariable::kVar_pt0U, &BuiltInVariable::kVar_pt1B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0U1C0C1C[4] = {&BuiltInVariable::kVar_pt0U, &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0U2B0B1C[4] = {&BuiltInVariable::kVar_pt0U, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0U2B1B1B1C[5] = {
+    &BuiltInVariable::kVar_pt0U, &BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt1B,
+    &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0U2B1C0B[4] = {&BuiltInVariable::kVar_pt0U, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0U3B0B1C[4] = {&BuiltInVariable::kVar_pt0U, &BuiltInVariable::kVar_pt3B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0U3B1B1B1C[5] = {
+    &BuiltInVariable::kVar_pt0U, &BuiltInVariable::kVar_pt3B, &BuiltInVariable::kVar_pt1B,
+    &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0U3B1C0B[4] = {&BuiltInVariable::kVar_pt0U, &BuiltInVariable::kVar_pt3B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0V0C[2] = {&BuiltInVariable::kVar_pt0V, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0V2B0B2C[4] = {&BuiltInVariable::kVar_pt0V, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt2C};
+constexpr const TVariable *p0V2B2B2B2C[5] = {
+    &BuiltInVariable::kVar_pt0V, &BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt2B,
+    &BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt2C};
+constexpr const TVariable *p0V2B2C0B[4] = {&BuiltInVariable::kVar_pt0V, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt2C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0V2C0C2C[4] = {&BuiltInVariable::kVar_pt0V, &BuiltInVariable::kVar_pt2C,
+                                           &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt2C};
+constexpr const TVariable *p0V3B0B2C[4] = {&BuiltInVariable::kVar_pt0V, &BuiltInVariable::kVar_pt3B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt2C};
+constexpr const TVariable *p0V3B2B2B2C[5] = {
+    &BuiltInVariable::kVar_pt0V, &BuiltInVariable::kVar_pt3B, &BuiltInVariable::kVar_pt2B,
+    &BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt2C};
+constexpr const TVariable *p0V3B2C0B[4] = {&BuiltInVariable::kVar_pt0V, &BuiltInVariable::kVar_pt3B,
+                                           &BuiltInVariable::kVar_pt2C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0W0C[2]   = {&BuiltInVariable::kVar_pt0W, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0W2B0B[3] = {&BuiltInVariable::kVar_pt0W, &BuiltInVariable::kVar_pt2B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0W2B0C[3] = {&BuiltInVariable::kVar_pt0W, &BuiltInVariable::kVar_pt2B,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0W2B2B2B[4] = {&BuiltInVariable::kVar_pt0W, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt2B};
+constexpr const TVariable *p0X0C[2] = {&BuiltInVariable::kVar_pt0X, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0X2B0B1C[4] = {&BuiltInVariable::kVar_pt0X, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0X2B0C[3]   = {&BuiltInVariable::kVar_pt0X, &BuiltInVariable::kVar_pt2B,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0X2B1B1B1C[5] = {
+    &BuiltInVariable::kVar_pt0X, &BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt1B,
+    &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0X2B1C0B[4] = {&BuiltInVariable::kVar_pt0X, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0X2B1C0C[4] = {&BuiltInVariable::kVar_pt0X, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0X2C0C1C[4] = {&BuiltInVariable::kVar_pt0X, &BuiltInVariable::kVar_pt2C,
+                                           &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0Y1C0C[3]   = {&BuiltInVariable::kVar_pt0Y, &BuiltInVariable::kVar_pt1C,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0Z0C[2] = {&BuiltInVariable::kVar_pt0Z, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0Z1B0B1C[4] = {&BuiltInVariable::kVar_pt0Z, &BuiltInVariable::kVar_pt1B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0Z2B0B1C[4] = {&BuiltInVariable::kVar_pt0Z, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0Z2B1B1B1C[5] = {
+    &BuiltInVariable::kVar_pt0Z, &BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt1B,
+    &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0Z2B1C0B[4] = {&BuiltInVariable::kVar_pt0Z, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0Z3B0B1C[4] = {&BuiltInVariable::kVar_pt0Z, &BuiltInVariable::kVar_pt3B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0Z3B1B1B1C[5] = {
+    &BuiltInVariable::kVar_pt0Z, &BuiltInVariable::kVar_pt3B, &BuiltInVariable::kVar_pt1B,
+    &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0Z3B1C0B[4] = {&BuiltInVariable::kVar_pt0Z, &BuiltInVariable::kVar_pt3B,
+                                           &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0a0C[2]   = {&BuiltInVariable::kVar_pt0a, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0a2B0B[3] = {&BuiltInVariable::kVar_pt0a, &BuiltInVariable::kVar_pt2B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0a3B0B[3] = {&BuiltInVariable::kVar_pt0a, &BuiltInVariable::kVar_pt3B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p0a3B2B2B[4] = {&BuiltInVariable::kVar_pt0a, &BuiltInVariable::kVar_pt3B,
+                                           &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt2B};
+constexpr const TVariable *p0b0C[2] = {&BuiltInVariable::kVar_pt0b, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p0b2B0B1C[4] = {&BuiltInVariable::kVar_pt0b, &BuiltInVariable::kVar_pt2B,
+                                           &BuiltInVariable::kVar_pt0B,
+                                           &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0b3B1B1B1C[5] = {
+    &BuiltInVariable::kVar_pt0b, &BuiltInVariable::kVar_pt3B, &BuiltInVariable::kVar_pt1B,
+    &BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p0c1C3B[3]  = {&BuiltInVariable::kVar_pt0c, &BuiltInVariable::kVar_pt1C,
+                                         &BuiltInVariable::kVar_pt3B};
+constexpr const TVariable *p0d1C3C[3]  = {&BuiltInVariable::kVar_pt0d, &BuiltInVariable::kVar_pt1C,
+                                         &BuiltInVariable::kVar_pt3C};
+constexpr const TVariable *p0e1C3D[3]  = {&BuiltInVariable::kVar_pt0e, &BuiltInVariable::kVar_pt1C,
+                                         &BuiltInVariable::kVar_pt3D};
+constexpr const TVariable *p0f2C3B[3]  = {&BuiltInVariable::kVar_pt0f, &BuiltInVariable::kVar_pt2C,
+                                         &BuiltInVariable::kVar_pt3B};
+constexpr const TVariable *p0g2C3C[3]  = {&BuiltInVariable::kVar_pt0g, &BuiltInVariable::kVar_pt2C,
+                                         &BuiltInVariable::kVar_pt3C};
+constexpr const TVariable *p0h2C3D[3]  = {&BuiltInVariable::kVar_pt0h, &BuiltInVariable::kVar_pt2C,
+                                         &BuiltInVariable::kVar_pt3D};
+constexpr const TVariable *p0i2C3B[3]  = {&BuiltInVariable::kVar_pt0i, &BuiltInVariable::kVar_pt2C,
+                                         &BuiltInVariable::kVar_pt3B};
+constexpr const TVariable *p0j2C3C[3]  = {&BuiltInVariable::kVar_pt0j, &BuiltInVariable::kVar_pt2C,
+                                         &BuiltInVariable::kVar_pt3C};
+constexpr const TVariable *p0k2C3D[3]  = {&BuiltInVariable::kVar_pt0k, &BuiltInVariable::kVar_pt2C,
+                                         &BuiltInVariable::kVar_pt3D};
+constexpr const TVariable *p0l2C3B[3]  = {&BuiltInVariable::kVar_pt0l, &BuiltInVariable::kVar_pt2C,
+                                         &BuiltInVariable::kVar_pt3B};
+constexpr const TVariable *p0m2C3C[3]  = {&BuiltInVariable::kVar_pt0m, &BuiltInVariable::kVar_pt2C,
+                                         &BuiltInVariable::kVar_pt3C};
+constexpr const TVariable *p0n2C3D[3]  = {&BuiltInVariable::kVar_pt0n, &BuiltInVariable::kVar_pt2C,
+                                         &BuiltInVariable::kVar_pt3D};
+constexpr const TVariable *p1B0B0B[3]  = {&BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt0B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p1B1B0B[3]  = {&BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p1B1B1B[3]  = {&BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1B,
+                                         &BuiltInVariable::kVar_pt1B};
+constexpr const TVariable *p1B1B1E[3]  = {&BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1B,
+                                         &BuiltInVariable::kVar_pt1E};
+constexpr const TVariable *p1B1C[2]    = {&BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p1B2B[2]    = {&BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt2B};
+constexpr const TVariable *p1B3B[2]    = {&BuiltInVariable::kVar_pt1B, &BuiltInVariable::kVar_pt3B};
+constexpr const TVariable *p1B_o_1B[2] = {&BuiltInVariable::kVar_pt1B,
+                                          &BuiltInVariable::kVar_pt_o_1B};
+constexpr const TVariable *p1B_o_1C[2] = {&BuiltInVariable::kVar_pt1B,
+                                          &BuiltInVariable::kVar_pt_o_1C};
+constexpr const TVariable *p1C0C0C[3]  = {&BuiltInVariable::kVar_pt1C, &BuiltInVariable::kVar_pt0C,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p1C1C0C0C[4] = {&BuiltInVariable::kVar_pt1C, &BuiltInVariable::kVar_pt1C,
+                                           &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p1C1C1C[3]   = {&BuiltInVariable::kVar_pt1C, &BuiltInVariable::kVar_pt1C,
+                                         &BuiltInVariable::kVar_pt1C};
+constexpr const TVariable *p1C1C_o_1C_o_1C[4] = {
+    &BuiltInVariable::kVar_pt1C, &BuiltInVariable::kVar_pt1C, &BuiltInVariable::kVar_pt_o_1C,
+    &BuiltInVariable::kVar_pt_o_1C};
+constexpr const TVariable *p1D0C0C[3]   = {&BuiltInVariable::kVar_pt1D, &BuiltInVariable::kVar_pt0C,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p1D0D0D[3]   = {&BuiltInVariable::kVar_pt1D, &BuiltInVariable::kVar_pt0D,
+                                         &BuiltInVariable::kVar_pt0D};
+constexpr const TVariable *p1D1D0C0C[4] = {&BuiltInVariable::kVar_pt1D, &BuiltInVariable::kVar_pt1D,
+                                           &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p1D1D1D[3]   = {&BuiltInVariable::kVar_pt1D, &BuiltInVariable::kVar_pt1D,
+                                         &BuiltInVariable::kVar_pt1D};
+constexpr const TVariable *p1D1D_o_1D_o_1D[4] = {
+    &BuiltInVariable::kVar_pt1D, &BuiltInVariable::kVar_pt1D, &BuiltInVariable::kVar_pt_o_1D,
+    &BuiltInVariable::kVar_pt_o_1D};
+constexpr const TVariable *p1E1E[2]    = {&BuiltInVariable::kVar_pt1E, &BuiltInVariable::kVar_pt1E};
+constexpr const TVariable *p2B0B0B[3]  = {&BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt0B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p2B0G[2]    = {&BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt0G};
+constexpr const TVariable *p2B1B[2]    = {&BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt1B};
+constexpr const TVariable *p2B2B0B[3]  = {&BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt2B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p2B2B2B[3]  = {&BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt2B,
+                                         &BuiltInVariable::kVar_pt2B};
+constexpr const TVariable *p2B2B2E[3]  = {&BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt2B,
+                                         &BuiltInVariable::kVar_pt2E};
+constexpr const TVariable *p2B2C[2]    = {&BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt2C};
+constexpr const TVariable *p2B3B[2]    = {&BuiltInVariable::kVar_pt2B, &BuiltInVariable::kVar_pt3B};
+constexpr const TVariable *p2B_o_2B[2] = {&BuiltInVariable::kVar_pt2B,
+                                          &BuiltInVariable::kVar_pt_o_2B};
+constexpr const TVariable *p2B_o_2C[2] = {&BuiltInVariable::kVar_pt2B,
+                                          &BuiltInVariable::kVar_pt_o_2C};
+constexpr const TVariable *p2C0C0C[3]  = {&BuiltInVariable::kVar_pt2C, &BuiltInVariable::kVar_pt0C,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p2C2C0C0C[4] = {&BuiltInVariable::kVar_pt2C, &BuiltInVariable::kVar_pt2C,
+                                           &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p2C2C2C[3]   = {&BuiltInVariable::kVar_pt2C, &BuiltInVariable::kVar_pt2C,
+                                         &BuiltInVariable::kVar_pt2C};
+constexpr const TVariable *p2C2C_o_2C_o_2C[4] = {
+    &BuiltInVariable::kVar_pt2C, &BuiltInVariable::kVar_pt2C, &BuiltInVariable::kVar_pt_o_2C,
+    &BuiltInVariable::kVar_pt_o_2C};
+constexpr const TVariable *p2D0C0C[3]   = {&BuiltInVariable::kVar_pt2D, &BuiltInVariable::kVar_pt0C,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p2D0D0D[3]   = {&BuiltInVariable::kVar_pt2D, &BuiltInVariable::kVar_pt0D,
+                                         &BuiltInVariable::kVar_pt0D};
+constexpr const TVariable *p2D2D0C0C[4] = {&BuiltInVariable::kVar_pt2D, &BuiltInVariable::kVar_pt2D,
+                                           &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p2D2D2D[3]   = {&BuiltInVariable::kVar_pt2D, &BuiltInVariable::kVar_pt2D,
+                                         &BuiltInVariable::kVar_pt2D};
+constexpr const TVariable *p2D2D_o_2D_o_2D[4] = {
+    &BuiltInVariable::kVar_pt2D, &BuiltInVariable::kVar_pt2D, &BuiltInVariable::kVar_pt_o_2D,
+    &BuiltInVariable::kVar_pt_o_2D};
+constexpr const TVariable *p2E2E[2]    = {&BuiltInVariable::kVar_pt2E, &BuiltInVariable::kVar_pt2E};
+constexpr const TVariable *p3B0B0B[3]  = {&BuiltInVariable::kVar_pt3B, &BuiltInVariable::kVar_pt0B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p3B1B[2]    = {&BuiltInVariable::kVar_pt3B, &BuiltInVariable::kVar_pt1B};
+constexpr const TVariable *p3B2B[2]    = {&BuiltInVariable::kVar_pt3B, &BuiltInVariable::kVar_pt2B};
+constexpr const TVariable *p3B3B0B[3]  = {&BuiltInVariable::kVar_pt3B, &BuiltInVariable::kVar_pt3B,
+                                         &BuiltInVariable::kVar_pt0B};
+constexpr const TVariable *p3B3B3B[3]  = {&BuiltInVariable::kVar_pt3B, &BuiltInVariable::kVar_pt3B,
+                                         &BuiltInVariable::kVar_pt3B};
+constexpr const TVariable *p3B3B3E[3]  = {&BuiltInVariable::kVar_pt3B, &BuiltInVariable::kVar_pt3B,
+                                         &BuiltInVariable::kVar_pt3E};
+constexpr const TVariable *p3B3C[2]    = {&BuiltInVariable::kVar_pt3B, &BuiltInVariable::kVar_pt3C};
+constexpr const TVariable *p3B_o_3B[2] = {&BuiltInVariable::kVar_pt3B,
+                                          &BuiltInVariable::kVar_pt_o_3B};
+constexpr const TVariable *p3B_o_3C[2] = {&BuiltInVariable::kVar_pt3B,
+                                          &BuiltInVariable::kVar_pt_o_3C};
+constexpr const TVariable *p3C0C0C[3]  = {&BuiltInVariable::kVar_pt3C, &BuiltInVariable::kVar_pt0C,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p3C3C0C0C[4] = {&BuiltInVariable::kVar_pt3C, &BuiltInVariable::kVar_pt3C,
+                                           &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p3C3C3C[3]   = {&BuiltInVariable::kVar_pt3C, &BuiltInVariable::kVar_pt3C,
+                                         &BuiltInVariable::kVar_pt3C};
+constexpr const TVariable *p3C3C_o_3C_o_3C[4] = {
+    &BuiltInVariable::kVar_pt3C, &BuiltInVariable::kVar_pt3C, &BuiltInVariable::kVar_pt_o_3C,
+    &BuiltInVariable::kVar_pt_o_3C};
+constexpr const TVariable *p3D0C0C[3]   = {&BuiltInVariable::kVar_pt3D, &BuiltInVariable::kVar_pt0C,
+                                         &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p3D0D0D[3]   = {&BuiltInVariable::kVar_pt3D, &BuiltInVariable::kVar_pt0D,
+                                         &BuiltInVariable::kVar_pt0D};
+constexpr const TVariable *p3D3D0C0C[4] = {&BuiltInVariable::kVar_pt3D, &BuiltInVariable::kVar_pt3D,
+                                           &BuiltInVariable::kVar_pt0C,
+                                           &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p3D3D3D[3]   = {&BuiltInVariable::kVar_pt3D, &BuiltInVariable::kVar_pt3D,
+                                         &BuiltInVariable::kVar_pt3D};
+constexpr const TVariable *p3D3D_o_3D_o_3D[4] = {
+    &BuiltInVariable::kVar_pt3D, &BuiltInVariable::kVar_pt3D, &BuiltInVariable::kVar_pt_o_3D,
+    &BuiltInVariable::kVar_pt_o_3D};
+constexpr const TVariable *p3E3E[2] = {&BuiltInVariable::kVar_pt3E, &BuiltInVariable::kVar_pt3E};
+constexpr const TVariable *p5B5B[2] = {&BuiltInVariable::kVar_pt5B, &BuiltInVariable::kVar_pt5B};
+constexpr const TVariable *p6B6B[2] = {&BuiltInVariable::kVar_pt6B, &BuiltInVariable::kVar_pt6B};
+constexpr const TVariable *p7B7B[2] = {&BuiltInVariable::kVar_pt7B, &BuiltInVariable::kVar_pt7B};
+constexpr const TVariable *p9B9B[2] = {&BuiltInVariable::kVar_pt9B, &BuiltInVariable::kVar_pt9B};
+constexpr const TVariable *pABAB[2] = {&BuiltInVariable::kVar_ptAB, &BuiltInVariable::kVar_ptAB};
+constexpr const TVariable *pBBBB[2] = {&BuiltInVariable::kVar_ptBB, &BuiltInVariable::kVar_ptBB};
+constexpr const TVariable *pDBDB[2] = {&BuiltInVariable::kVar_ptDB, &BuiltInVariable::kVar_ptDB};
+constexpr const TVariable *pEBEB[2] = {&BuiltInVariable::kVar_ptEB, &BuiltInVariable::kVar_ptEB};
+constexpr const TVariable *pFBFB[2] = {&BuiltInVariable::kVar_ptFB, &BuiltInVariable::kVar_ptFB};
+constexpr const TVariable *p_io_0C0C0C[3] = {
+    &BuiltInVariable::kVar_pt_io_0C, &BuiltInVariable::kVar_pt0C, &BuiltInVariable::kVar_pt0C};
+constexpr const TVariable *p_io_0D0D0D[3] = {
+    &BuiltInVariable::kVar_pt_io_0D, &BuiltInVariable::kVar_pt0D, &BuiltInVariable::kVar_pt0D};
+
+}  // namespace BuiltInParameters
+
+namespace UnmangledBuiltIns
+{
+
+constexpr const UnmangledBuiltIn ARB_texture_rectangle(TExtension::ARB_texture_rectangle);
+constexpr const UnmangledBuiltIn EXT_YUV_target(TExtension::EXT_YUV_target);
+constexpr const UnmangledBuiltIn EXT_geometry_shader(TExtension::EXT_geometry_shader);
+constexpr const UnmangledBuiltIn EXT_shader_texture_lod(TExtension::EXT_shader_texture_lod);
+constexpr const UnmangledBuiltIn OES_standard_derivatives(TExtension::OES_standard_derivatives);
+constexpr const UnmangledBuiltIn UNDEFINED(TExtension::UNDEFINED);
+
+}  // namespace UnmangledBuiltIns
+
+// 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 BuiltInFunction
+{
+
+constexpr const TFunction kFunction_radians_0B(
+    BuiltInId::radians_Float1,
+    BuiltInName::radians,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpRadians,
+    true);
+constexpr const TFunction kFunction_radians_1B(
+    BuiltInId::radians_Float2,
+    BuiltInName::radians,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpRadians,
+    true);
+constexpr const TFunction kFunction_radians_2B(
+    BuiltInId::radians_Float3,
+    BuiltInName::radians,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpRadians,
+    true);
+constexpr const TFunction kFunction_radians_3B(
+    BuiltInId::radians_Float4,
+    BuiltInName::radians,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpRadians,
+    true);
+constexpr const TFunction kFunction_degrees_0B(
+    BuiltInId::degrees_Float1,
+    BuiltInName::degrees,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpDegrees,
+    true);
+constexpr const TFunction kFunction_degrees_1B(
+    BuiltInId::degrees_Float2,
+    BuiltInName::degrees,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpDegrees,
+    true);
+constexpr const TFunction kFunction_degrees_2B(
+    BuiltInId::degrees_Float3,
+    BuiltInName::degrees,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpDegrees,
+    true);
+constexpr const TFunction kFunction_degrees_3B(
+    BuiltInId::degrees_Float4,
+    BuiltInName::degrees,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpDegrees,
+    true);
+constexpr const TFunction kFunction_sin_0B(
+    BuiltInId::sin_Float1,
+    BuiltInName::sin,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpSin,
+    true);
+constexpr const TFunction kFunction_sin_1B(
+    BuiltInId::sin_Float2,
+    BuiltInName::sin,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpSin,
+    true);
+constexpr const TFunction kFunction_sin_2B(
+    BuiltInId::sin_Float3,
+    BuiltInName::sin,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpSin,
+    true);
+constexpr const TFunction kFunction_sin_3B(
+    BuiltInId::sin_Float4,
+    BuiltInName::sin,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpSin,
+    true);
+constexpr const TFunction kFunction_cos_0B(
+    BuiltInId::cos_Float1,
+    BuiltInName::cos,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCos,
+    true);
+constexpr const TFunction kFunction_cos_1B(
+    BuiltInId::cos_Float2,
+    BuiltInName::cos,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCos,
+    true);
+constexpr const TFunction kFunction_cos_2B(
+    BuiltInId::cos_Float3,
+    BuiltInName::cos,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCos,
+    true);
+constexpr const TFunction kFunction_cos_3B(
+    BuiltInId::cos_Float4,
+    BuiltInName::cos,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCos,
+    true);
+constexpr const TFunction kFunction_tan_0B(
+    BuiltInId::tan_Float1,
+    BuiltInName::tan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpTan,
+    true);
+constexpr const TFunction kFunction_tan_1B(
+    BuiltInId::tan_Float2,
+    BuiltInName::tan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpTan,
+    true);
+constexpr const TFunction kFunction_tan_2B(
+    BuiltInId::tan_Float3,
+    BuiltInName::tan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpTan,
+    true);
+constexpr const TFunction kFunction_tan_3B(
+    BuiltInId::tan_Float4,
+    BuiltInName::tan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpTan,
+    true);
+constexpr const TFunction kFunction_asin_0B(
+    BuiltInId::asin_Float1,
+    BuiltInName::asin,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpAsin,
+    true);
+constexpr const TFunction kFunction_asin_1B(
+    BuiltInId::asin_Float2,
+    BuiltInName::asin,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpAsin,
+    true);
+constexpr const TFunction kFunction_asin_2B(
+    BuiltInId::asin_Float3,
+    BuiltInName::asin,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpAsin,
+    true);
+constexpr const TFunction kFunction_asin_3B(
+    BuiltInId::asin_Float4,
+    BuiltInName::asin,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpAsin,
+    true);
+constexpr const TFunction kFunction_acos_0B(
+    BuiltInId::acos_Float1,
+    BuiltInName::acos,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpAcos,
+    true);
+constexpr const TFunction kFunction_acos_1B(
+    BuiltInId::acos_Float2,
+    BuiltInName::acos,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpAcos,
+    true);
+constexpr const TFunction kFunction_acos_2B(
+    BuiltInId::acos_Float3,
+    BuiltInName::acos,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpAcos,
+    true);
+constexpr const TFunction kFunction_acos_3B(
+    BuiltInId::acos_Float4,
+    BuiltInName::acos,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpAcos,
+    true);
+constexpr const TFunction kFunction_atan_0B0B(
+    BuiltInId::atan_Float1_Float1,
+    BuiltInName::atan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B1B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpAtan,
+    true);
+constexpr const TFunction kFunction_atan_1B1B(
+    BuiltInId::atan_Float2_Float2,
+    BuiltInName::atan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpAtan,
+    true);
+constexpr const TFunction kFunction_atan_2B2B(
+    BuiltInId::atan_Float3_Float3,
+    BuiltInName::atan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpAtan,
+    true);
+constexpr const TFunction kFunction_atan_3B3B(
+    BuiltInId::atan_Float4_Float4,
+    BuiltInName::atan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpAtan,
+    true);
+constexpr const TFunction kFunction_atan_0B(
+    BuiltInId::atan_Float1,
+    BuiltInName::atan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpAtan,
+    true);
+constexpr const TFunction kFunction_atan_1B(
+    BuiltInId::atan_Float2,
+    BuiltInName::atan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpAtan,
+    true);
+constexpr const TFunction kFunction_atan_2B(
+    BuiltInId::atan_Float3,
+    BuiltInName::atan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpAtan,
+    true);
+constexpr const TFunction kFunction_atan_3B(
+    BuiltInId::atan_Float4,
+    BuiltInName::atan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpAtan,
+    true);
+constexpr const TFunction kFunction_sinh_0B(
+    BuiltInId::sinh_Float1,
+    BuiltInName::sinh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpSinh,
+    true);
+constexpr const TFunction kFunction_sinh_1B(
+    BuiltInId::sinh_Float2,
+    BuiltInName::sinh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpSinh,
+    true);
+constexpr const TFunction kFunction_sinh_2B(
+    BuiltInId::sinh_Float3,
+    BuiltInName::sinh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpSinh,
+    true);
+constexpr const TFunction kFunction_sinh_3B(
+    BuiltInId::sinh_Float4,
+    BuiltInName::sinh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpSinh,
+    true);
+constexpr const TFunction kFunction_cosh_0B(
+    BuiltInId::cosh_Float1,
+    BuiltInName::cosh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCosh,
+    true);
+constexpr const TFunction kFunction_cosh_1B(
+    BuiltInId::cosh_Float2,
+    BuiltInName::cosh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCosh,
+    true);
+constexpr const TFunction kFunction_cosh_2B(
+    BuiltInId::cosh_Float3,
+    BuiltInName::cosh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCosh,
+    true);
+constexpr const TFunction kFunction_cosh_3B(
+    BuiltInId::cosh_Float4,
+    BuiltInName::cosh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCosh,
+    true);
+constexpr const TFunction kFunction_tanh_0B(
+    BuiltInId::tanh_Float1,
+    BuiltInName::tanh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpTanh,
+    true);
+constexpr const TFunction kFunction_tanh_1B(
+    BuiltInId::tanh_Float2,
+    BuiltInName::tanh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpTanh,
+    true);
+constexpr const TFunction kFunction_tanh_2B(
+    BuiltInId::tanh_Float3,
+    BuiltInName::tanh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpTanh,
+    true);
+constexpr const TFunction kFunction_tanh_3B(
+    BuiltInId::tanh_Float4,
+    BuiltInName::tanh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpTanh,
+    true);
+constexpr const TFunction kFunction_asinh_0B(
+    BuiltInId::asinh_Float1,
+    BuiltInName::asinh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpAsinh,
+    true);
+constexpr const TFunction kFunction_asinh_1B(
+    BuiltInId::asinh_Float2,
+    BuiltInName::asinh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpAsinh,
+    true);
+constexpr const TFunction kFunction_asinh_2B(
+    BuiltInId::asinh_Float3,
+    BuiltInName::asinh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpAsinh,
+    true);
+constexpr const TFunction kFunction_asinh_3B(
+    BuiltInId::asinh_Float4,
+    BuiltInName::asinh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpAsinh,
+    true);
+constexpr const TFunction kFunction_acosh_0B(
+    BuiltInId::acosh_Float1,
+    BuiltInName::acosh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpAcosh,
+    true);
+constexpr const TFunction kFunction_acosh_1B(
+    BuiltInId::acosh_Float2,
+    BuiltInName::acosh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpAcosh,
+    true);
+constexpr const TFunction kFunction_acosh_2B(
+    BuiltInId::acosh_Float3,
+    BuiltInName::acosh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpAcosh,
+    true);
+constexpr const TFunction kFunction_acosh_3B(
+    BuiltInId::acosh_Float4,
+    BuiltInName::acosh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpAcosh,
+    true);
+constexpr const TFunction kFunction_atanh_0B(
+    BuiltInId::atanh_Float1,
+    BuiltInName::atanh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpAtanh,
+    true);
+constexpr const TFunction kFunction_atanh_1B(
+    BuiltInId::atanh_Float2,
+    BuiltInName::atanh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpAtanh,
+    true);
+constexpr const TFunction kFunction_atanh_2B(
+    BuiltInId::atanh_Float3,
+    BuiltInName::atanh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpAtanh,
+    true);
+constexpr const TFunction kFunction_atanh_3B(
+    BuiltInId::atanh_Float4,
+    BuiltInName::atanh,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpAtanh,
+    true);
+constexpr const TFunction kFunction_pow_0B0B(
+    BuiltInId::pow_Float1_Float1,
+    BuiltInName::pow,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B1B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpPow,
+    true);
+constexpr const TFunction kFunction_pow_1B1B(
+    BuiltInId::pow_Float2_Float2,
+    BuiltInName::pow,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpPow,
+    true);
+constexpr const TFunction kFunction_pow_2B2B(
+    BuiltInId::pow_Float3_Float3,
+    BuiltInName::pow,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpPow,
+    true);
+constexpr const TFunction kFunction_pow_3B3B(
+    BuiltInId::pow_Float4_Float4,
+    BuiltInName::pow,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpPow,
+    true);
+constexpr const TFunction kFunction_exp_0B(
+    BuiltInId::exp_Float1,
+    BuiltInName::exp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpExp,
+    true);
+constexpr const TFunction kFunction_exp_1B(
+    BuiltInId::exp_Float2,
+    BuiltInName::exp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpExp,
+    true);
+constexpr const TFunction kFunction_exp_2B(
+    BuiltInId::exp_Float3,
+    BuiltInName::exp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpExp,
+    true);
+constexpr const TFunction kFunction_exp_3B(
+    BuiltInId::exp_Float4,
+    BuiltInName::exp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpExp,
+    true);
+constexpr const TFunction kFunction_log_0B(
+    BuiltInId::log_Float1,
+    BuiltInName::log,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpLog,
+    true);
+constexpr const TFunction kFunction_log_1B(
+    BuiltInId::log_Float2,
+    BuiltInName::log,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpLog,
+    true);
+constexpr const TFunction kFunction_log_2B(
+    BuiltInId::log_Float3,
+    BuiltInName::log,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpLog,
+    true);
+constexpr const TFunction kFunction_log_3B(
+    BuiltInId::log_Float4,
+    BuiltInName::log,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpLog,
+    true);
+constexpr const TFunction kFunction_exp2_0B(
+    BuiltInId::exp2_Float1,
+    BuiltInName::exp2,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpExp2,
+    true);
+constexpr const TFunction kFunction_exp2_1B(
+    BuiltInId::exp2_Float2,
+    BuiltInName::exp2,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpExp2,
+    true);
+constexpr const TFunction kFunction_exp2_2B(
+    BuiltInId::exp2_Float3,
+    BuiltInName::exp2,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpExp2,
+    true);
+constexpr const TFunction kFunction_exp2_3B(
+    BuiltInId::exp2_Float4,
+    BuiltInName::exp2,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpExp2,
+    true);
+constexpr const TFunction kFunction_log2_0B(
+    BuiltInId::log2_Float1,
+    BuiltInName::log2,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpLog2,
+    true);
+constexpr const TFunction kFunction_log2_1B(
+    BuiltInId::log2_Float2,
+    BuiltInName::log2,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpLog2,
+    true);
+constexpr const TFunction kFunction_log2_2B(
+    BuiltInId::log2_Float3,
+    BuiltInName::log2,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpLog2,
+    true);
+constexpr const TFunction kFunction_log2_3B(
+    BuiltInId::log2_Float4,
+    BuiltInName::log2,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpLog2,
+    true);
+constexpr const TFunction kFunction_sqrt_0B(
+    BuiltInId::sqrt_Float1,
+    BuiltInName::sqrt,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpSqrt,
+    true);
+constexpr const TFunction kFunction_sqrt_1B(
+    BuiltInId::sqrt_Float2,
+    BuiltInName::sqrt,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpSqrt,
+    true);
+constexpr const TFunction kFunction_sqrt_2B(
+    BuiltInId::sqrt_Float3,
+    BuiltInName::sqrt,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpSqrt,
+    true);
+constexpr const TFunction kFunction_sqrt_3B(
+    BuiltInId::sqrt_Float4,
+    BuiltInName::sqrt,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpSqrt,
+    true);
+constexpr const TFunction kFunction_inversesqrt_0B(
+    BuiltInId::inversesqrt_Float1,
+    BuiltInName::inversesqrt,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpInversesqrt,
+    true);
+constexpr const TFunction kFunction_inversesqrt_1B(
+    BuiltInId::inversesqrt_Float2,
+    BuiltInName::inversesqrt,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpInversesqrt,
+    true);
+constexpr const TFunction kFunction_inversesqrt_2B(
+    BuiltInId::inversesqrt_Float3,
+    BuiltInName::inversesqrt,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpInversesqrt,
+    true);
+constexpr const TFunction kFunction_inversesqrt_3B(
+    BuiltInId::inversesqrt_Float4,
+    BuiltInName::inversesqrt,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpInversesqrt,
+    true);
+constexpr const TFunction kFunction_abs_0B(
+    BuiltInId::abs_Float1,
+    BuiltInName::abs,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpAbs,
+    true);
+constexpr const TFunction kFunction_abs_1B(
+    BuiltInId::abs_Float2,
+    BuiltInName::abs,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpAbs,
+    true);
+constexpr const TFunction kFunction_abs_2B(
+    BuiltInId::abs_Float3,
+    BuiltInName::abs,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpAbs,
+    true);
+constexpr const TFunction kFunction_abs_3B(
+    BuiltInId::abs_Float4,
+    BuiltInName::abs,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpAbs,
+    true);
+constexpr const TFunction kFunction_abs_0C(BuiltInId::abs_Int1,
+                                           BuiltInName::abs,
+                                           TExtension::UNDEFINED,
+                                           BuiltInParameters::p0C0C_o_0C_o_0C,
+                                           1,
+                                           StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+                                           EOpAbs,
+                                           true);
+constexpr const TFunction kFunction_abs_1C(BuiltInId::abs_Int2,
+                                           BuiltInName::abs,
+                                           TExtension::UNDEFINED,
+                                           BuiltInParameters::p1C1C0C0C,
+                                           1,
+                                           StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+                                           EOpAbs,
+                                           true);
+constexpr const TFunction kFunction_abs_2C(BuiltInId::abs_Int3,
+                                           BuiltInName::abs,
+                                           TExtension::UNDEFINED,
+                                           BuiltInParameters::p2C2C0C0C,
+                                           1,
+                                           StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+                                           EOpAbs,
+                                           true);
+constexpr const TFunction kFunction_abs_3C(BuiltInId::abs_Int4,
+                                           BuiltInName::abs,
+                                           TExtension::UNDEFINED,
+                                           BuiltInParameters::p3C0C0C,
+                                           1,
+                                           StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+                                           EOpAbs,
+                                           true);
+constexpr const TFunction kFunction_sign_0B(
+    BuiltInId::sign_Float1,
+    BuiltInName::sign,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpSign,
+    true);
+constexpr const TFunction kFunction_sign_1B(
+    BuiltInId::sign_Float2,
+    BuiltInName::sign,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpSign,
+    true);
+constexpr const TFunction kFunction_sign_2B(
+    BuiltInId::sign_Float3,
+    BuiltInName::sign,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpSign,
+    true);
+constexpr const TFunction kFunction_sign_3B(
+    BuiltInId::sign_Float4,
+    BuiltInName::sign,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpSign,
+    true);
+constexpr const TFunction kFunction_sign_0C(
+    BuiltInId::sign_Int1,
+    BuiltInName::sign,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0C0C_o_0C_o_0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpSign,
+    true);
+constexpr const TFunction kFunction_sign_1C(
+    BuiltInId::sign_Int2,
+    BuiltInName::sign,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C1C0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpSign,
+    true);
+constexpr const TFunction kFunction_sign_2C(
+    BuiltInId::sign_Int3,
+    BuiltInName::sign,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C2C0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpSign,
+    true);
+constexpr const TFunction kFunction_sign_3C(
+    BuiltInId::sign_Int4,
+    BuiltInName::sign,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpSign,
+    true);
+constexpr const TFunction kFunction_floor_0B(
+    BuiltInId::floor_Float1,
+    BuiltInName::floor,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpFloor,
+    true);
+constexpr const TFunction kFunction_floor_1B(
+    BuiltInId::floor_Float2,
+    BuiltInName::floor,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpFloor,
+    true);
+constexpr const TFunction kFunction_floor_2B(
+    BuiltInId::floor_Float3,
+    BuiltInName::floor,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpFloor,
+    true);
+constexpr const TFunction kFunction_floor_3B(
+    BuiltInId::floor_Float4,
+    BuiltInName::floor,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpFloor,
+    true);
+constexpr const TFunction kFunction_trunc_0B(
+    BuiltInId::trunc_Float1,
+    BuiltInName::trunc,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpTrunc,
+    true);
+constexpr const TFunction kFunction_trunc_1B(
+    BuiltInId::trunc_Float2,
+    BuiltInName::trunc,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpTrunc,
+    true);
+constexpr const TFunction kFunction_trunc_2B(
+    BuiltInId::trunc_Float3,
+    BuiltInName::trunc,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpTrunc,
+    true);
+constexpr const TFunction kFunction_trunc_3B(
+    BuiltInId::trunc_Float4,
+    BuiltInName::trunc,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpTrunc,
+    true);
+constexpr const TFunction kFunction_round_0B(
+    BuiltInId::round_Float1,
+    BuiltInName::round,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpRound,
+    true);
+constexpr const TFunction kFunction_round_1B(
+    BuiltInId::round_Float2,
+    BuiltInName::round,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpRound,
+    true);
+constexpr const TFunction kFunction_round_2B(
+    BuiltInId::round_Float3,
+    BuiltInName::round,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpRound,
+    true);
+constexpr const TFunction kFunction_round_3B(
+    BuiltInId::round_Float4,
+    BuiltInName::round,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpRound,
+    true);
+constexpr const TFunction kFunction_roundEven_0B(
+    BuiltInId::roundEven_Float1,
+    BuiltInName::roundEven,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpRoundEven,
+    true);
+constexpr const TFunction kFunction_roundEven_1B(
+    BuiltInId::roundEven_Float2,
+    BuiltInName::roundEven,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpRoundEven,
+    true);
+constexpr const TFunction kFunction_roundEven_2B(
+    BuiltInId::roundEven_Float3,
+    BuiltInName::roundEven,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpRoundEven,
+    true);
+constexpr const TFunction kFunction_roundEven_3B(
+    BuiltInId::roundEven_Float4,
+    BuiltInName::roundEven,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpRoundEven,
+    true);
+constexpr const TFunction kFunction_ceil_0B(
+    BuiltInId::ceil_Float1,
+    BuiltInName::ceil,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCeil,
+    true);
+constexpr const TFunction kFunction_ceil_1B(
+    BuiltInId::ceil_Float2,
+    BuiltInName::ceil,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCeil,
+    true);
+constexpr const TFunction kFunction_ceil_2B(
+    BuiltInId::ceil_Float3,
+    BuiltInName::ceil,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCeil,
+    true);
+constexpr const TFunction kFunction_ceil_3B(
+    BuiltInId::ceil_Float4,
+    BuiltInName::ceil,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCeil,
+    true);
+constexpr const TFunction kFunction_fract_0B(
+    BuiltInId::fract_Float1,
+    BuiltInName::fract,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpFract,
+    true);
+constexpr const TFunction kFunction_fract_1B(
+    BuiltInId::fract_Float2,
+    BuiltInName::fract,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpFract,
+    true);
+constexpr const TFunction kFunction_fract_2B(
+    BuiltInId::fract_Float3,
+    BuiltInName::fract,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpFract,
+    true);
+constexpr const TFunction kFunction_fract_3B(
+    BuiltInId::fract_Float4,
+    BuiltInName::fract,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpFract,
+    true);
+constexpr const TFunction kFunction_mod_0B0B(
+    BuiltInId::mod_Float1_Float1,
+    BuiltInName::mod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B1B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpMod,
+    true);
+constexpr const TFunction kFunction_mod_1B0B(
+    BuiltInId::mod_Float2_Float1,
+    BuiltInName::mod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B0B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpMod,
+    true);
+constexpr const TFunction kFunction_mod_2B0B(
+    BuiltInId::mod_Float3_Float1,
+    BuiltInName::mod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B0B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpMod,
+    true);
+constexpr const TFunction kFunction_mod_3B0B(
+    BuiltInId::mod_Float4_Float1,
+    BuiltInName::mod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B0B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpMod,
+    true);
+constexpr const TFunction kFunction_mod_1B1B(
+    BuiltInId::mod_Float2_Float2,
+    BuiltInName::mod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpMod,
+    true);
+constexpr const TFunction kFunction_mod_2B2B(
+    BuiltInId::mod_Float3_Float3,
+    BuiltInName::mod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpMod,
+    true);
+constexpr const TFunction kFunction_mod_3B3B(
+    BuiltInId::mod_Float4_Float4,
+    BuiltInName::mod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpMod,
+    true);
+constexpr const TFunction kFunction_min_0B0B(
+    BuiltInId::min_Float1_Float1,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B1B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_1B0B(
+    BuiltInId::min_Float2_Float1,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B0B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_2B0B(
+    BuiltInId::min_Float3_Float1,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B0B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_3B0B(
+    BuiltInId::min_Float4_Float1,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B0B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_1B1B(
+    BuiltInId::min_Float2_Float2,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_2B2B(
+    BuiltInId::min_Float3_Float3,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_3B3B(
+    BuiltInId::min_Float4_Float4,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_0C0C(
+    BuiltInId::min_Int1_Int1,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0C0C_o_0C_o_0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_1C1C(
+    BuiltInId::min_Int2_Int2,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C1C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_2C2C(
+    BuiltInId::min_Int3_Int3,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C2C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_3C3C(
+    BuiltInId::min_Int4_Int4,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C3C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_1C0C(
+    BuiltInId::min_Int2_Int1,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_2C0C(
+    BuiltInId::min_Int3_Int1,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_3C0C(
+    BuiltInId::min_Int4_Int1,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_0D0D(
+    BuiltInId::min_UInt1_UInt1,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0D0C0C,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_1D1D(
+    BuiltInId::min_UInt2_UInt2,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D1D0C0C,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_2D2D(
+    BuiltInId::min_UInt3_UInt3,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D0C0C,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_3D3D(
+    BuiltInId::min_UInt4_UInt4,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D3D0C0C,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_1D0D(
+    BuiltInId::min_UInt2_UInt1,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D0D0D,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_2D0D(
+    BuiltInId::min_UInt3_UInt1,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D0D0D,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_min_3D0D(
+    BuiltInId::min_UInt4_UInt1,
+    BuiltInName::min,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D0D0D,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpMin,
+    true);
+constexpr const TFunction kFunction_max_0B0B(
+    BuiltInId::max_Float1_Float1,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B1B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_1B0B(
+    BuiltInId::max_Float2_Float1,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B0B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_2B0B(
+    BuiltInId::max_Float3_Float1,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B0B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_3B0B(
+    BuiltInId::max_Float4_Float1,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B0B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_1B1B(
+    BuiltInId::max_Float2_Float2,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_2B2B(
+    BuiltInId::max_Float3_Float3,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_3B3B(
+    BuiltInId::max_Float4_Float4,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_0C0C(
+    BuiltInId::max_Int1_Int1,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0C0C_o_0C_o_0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_1C1C(
+    BuiltInId::max_Int2_Int2,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C1C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_2C2C(
+    BuiltInId::max_Int3_Int3,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C2C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_3C3C(
+    BuiltInId::max_Int4_Int4,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C3C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_1C0C(
+    BuiltInId::max_Int2_Int1,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_2C0C(
+    BuiltInId::max_Int3_Int1,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_3C0C(
+    BuiltInId::max_Int4_Int1,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_0D0D(
+    BuiltInId::max_UInt1_UInt1,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0D0C0C,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_1D1D(
+    BuiltInId::max_UInt2_UInt2,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D1D0C0C,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_2D2D(
+    BuiltInId::max_UInt3_UInt3,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D0C0C,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_3D3D(
+    BuiltInId::max_UInt4_UInt4,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D3D0C0C,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_1D0D(
+    BuiltInId::max_UInt2_UInt1,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D0D0D,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_2D0D(
+    BuiltInId::max_UInt3_UInt1,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D0D0D,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_max_3D0D(
+    BuiltInId::max_UInt4_UInt1,
+    BuiltInName::max,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D0D0D,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpMax,
+    true);
+constexpr const TFunction kFunction_clamp_0B0B0B(
+    BuiltInId::clamp_Float1_Float1_Float1,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_1B0B0B(
+    BuiltInId::clamp_Float2_Float1_Float1,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B0B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_2B0B0B(
+    BuiltInId::clamp_Float3_Float1_Float1,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B0B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_3B0B0B(
+    BuiltInId::clamp_Float4_Float1_Float1,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B0B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_1B1B1B(
+    BuiltInId::clamp_Float2_Float2_Float2,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B1B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_2B2B2B(
+    BuiltInId::clamp_Float3_Float3_Float3,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B2B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_3B3B3B(
+    BuiltInId::clamp_Float4_Float4_Float4,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_0C0C0C(
+    BuiltInId::clamp_Int1_Int1_Int1,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0C0C0C0C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_1C0C0C(
+    BuiltInId::clamp_Int2_Int1_Int1,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C0C0C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_2C0C0C(
+    BuiltInId::clamp_Int3_Int1_Int1,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C0C0C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_3C0C0C(
+    BuiltInId::clamp_Int4_Int1_Int1,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C0C0C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_1C1C1C(
+    BuiltInId::clamp_Int2_Int2_Int2,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C1C1C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_2C2C2C(
+    BuiltInId::clamp_Int3_Int3_Int3,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C2C2C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_3C3C3C(
+    BuiltInId::clamp_Int4_Int4_Int4,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C3C3C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_0D0D0D(
+    BuiltInId::clamp_UInt1_UInt1_UInt1,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0D0D,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_1D0D0D(
+    BuiltInId::clamp_UInt2_UInt1_UInt1,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D0D0D,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_2D0D0D(
+    BuiltInId::clamp_UInt3_UInt1_UInt1,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D0D0D,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_3D0D0D(
+    BuiltInId::clamp_UInt4_UInt1_UInt1,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D0D0D,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_1D1D1D(
+    BuiltInId::clamp_UInt2_UInt2_UInt2,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D1D1D,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_2D2D2D(
+    BuiltInId::clamp_UInt3_UInt3_UInt3,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D2D,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_clamp_3D3D3D(
+    BuiltInId::clamp_UInt4_UInt4_UInt4,
+    BuiltInName::clamp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D3D3D,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpClamp,
+    true);
+constexpr const TFunction kFunction_mix_0B0B0B(
+    BuiltInId::mix_Float1_Float1_Float1,
+    BuiltInName::mix,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpMix,
+    true);
+constexpr const TFunction kFunction_mix_1B1B0B(
+    BuiltInId::mix_Float2_Float2_Float1,
+    BuiltInName::mix,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpMix,
+    true);
+constexpr const TFunction kFunction_mix_2B2B0B(
+    BuiltInId::mix_Float3_Float3_Float1,
+    BuiltInName::mix,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpMix,
+    true);
+constexpr const TFunction kFunction_mix_3B3B0B(
+    BuiltInId::mix_Float4_Float4_Float1,
+    BuiltInName::mix,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpMix,
+    true);
+constexpr const TFunction kFunction_mix_1B1B1B(
+    BuiltInId::mix_Float2_Float2_Float2,
+    BuiltInName::mix,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B1B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpMix,
+    true);
+constexpr const TFunction kFunction_mix_2B2B2B(
+    BuiltInId::mix_Float3_Float3_Float3,
+    BuiltInName::mix,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B2B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpMix,
+    true);
+constexpr const TFunction kFunction_mix_3B3B3B(
+    BuiltInId::mix_Float4_Float4_Float4,
+    BuiltInName::mix,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpMix,
+    true);
+constexpr const TFunction kFunction_mix_0B0B0E(
+    BuiltInId::mix_Float1_Float1_Bool1,
+    BuiltInName::mix,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B0E,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpMix,
+    true);
+constexpr const TFunction kFunction_mix_1B1B1E(
+    BuiltInId::mix_Float2_Float2_Bool2,
+    BuiltInName::mix,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B1E,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpMix,
+    true);
+constexpr const TFunction kFunction_mix_2B2B2E(
+    BuiltInId::mix_Float3_Float3_Bool3,
+    BuiltInName::mix,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B2E,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpMix,
+    true);
+constexpr const TFunction kFunction_mix_3B3B3E(
+    BuiltInId::mix_Float4_Float4_Bool4,
+    BuiltInName::mix,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3E,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpMix,
+    true);
+constexpr const TFunction kFunction_step_0B0B(
+    BuiltInId::step_Float1_Float1,
+    BuiltInName::step,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B1B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpStep,
+    true);
+constexpr const TFunction kFunction_step_1B1B(
+    BuiltInId::step_Float2_Float2,
+    BuiltInName::step,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpStep,
+    true);
+constexpr const TFunction kFunction_step_2B2B(
+    BuiltInId::step_Float3_Float3,
+    BuiltInName::step,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpStep,
+    true);
+constexpr const TFunction kFunction_step_3B3B(
+    BuiltInId::step_Float4_Float4,
+    BuiltInName::step,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpStep,
+    true);
+constexpr const TFunction kFunction_step_0B1B(
+    BuiltInId::step_Float1_Float2,
+    BuiltInName::step,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B1B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpStep,
+    true);
+constexpr const TFunction kFunction_step_0B2B(
+    BuiltInId::step_Float1_Float3,
+    BuiltInName::step,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B2B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpStep,
+    true);
+constexpr const TFunction kFunction_step_0B3B(
+    BuiltInId::step_Float1_Float4,
+    BuiltInName::step,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpStep,
+    true);
+constexpr const TFunction kFunction_smoothstep_0B0B0B(
+    BuiltInId::smoothstep_Float1_Float1_Float1,
+    BuiltInName::smoothstep,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpSmoothstep,
+    true);
+constexpr const TFunction kFunction_smoothstep_1B1B1B(
+    BuiltInId::smoothstep_Float2_Float2_Float2,
+    BuiltInName::smoothstep,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B1B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpSmoothstep,
+    true);
+constexpr const TFunction kFunction_smoothstep_2B2B2B(
+    BuiltInId::smoothstep_Float3_Float3_Float3,
+    BuiltInName::smoothstep,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B2B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpSmoothstep,
+    true);
+constexpr const TFunction kFunction_smoothstep_3B3B3B(
+    BuiltInId::smoothstep_Float4_Float4_Float4,
+    BuiltInName::smoothstep,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpSmoothstep,
+    true);
+constexpr const TFunction kFunction_smoothstep_0B0B1B(
+    BuiltInId::smoothstep_Float1_Float1_Float2,
+    BuiltInName::smoothstep,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B1B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpSmoothstep,
+    true);
+constexpr const TFunction kFunction_smoothstep_0B0B2B(
+    BuiltInId::smoothstep_Float1_Float1_Float3,
+    BuiltInName::smoothstep,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B2B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpSmoothstep,
+    true);
+constexpr const TFunction kFunction_smoothstep_0B0B3B(
+    BuiltInId::smoothstep_Float1_Float1_Float4,
+    BuiltInName::smoothstep,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B3B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpSmoothstep,
+    true);
+constexpr const TFunction kFunction_modf_0B0B(
+    BuiltInId::modf_Float1_Float1,
+    BuiltInName::modf,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B_o_0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpModf,
+    false);
+constexpr const TFunction kFunction_modf_1B1B(
+    BuiltInId::modf_Float2_Float2,
+    BuiltInName::modf,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B_o_1B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpModf,
+    false);
+constexpr const TFunction kFunction_modf_2B2B(
+    BuiltInId::modf_Float3_Float3,
+    BuiltInName::modf,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B_o_2B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpModf,
+    false);
+constexpr const TFunction kFunction_modf_3B3B(
+    BuiltInId::modf_Float4_Float4,
+    BuiltInName::modf,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B_o_3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpModf,
+    false);
+constexpr const TFunction kFunction_isnan_0B(
+    BuiltInId::isnan_Float1,
+    BuiltInName::isnan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpIsnan,
+    true);
+constexpr const TFunction kFunction_isnan_1B(
+    BuiltInId::isnan_Float2,
+    BuiltInName::isnan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpIsnan,
+    true);
+constexpr const TFunction kFunction_isnan_2B(
+    BuiltInId::isnan_Float3,
+    BuiltInName::isnan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpIsnan,
+    true);
+constexpr const TFunction kFunction_isnan_3B(
+    BuiltInId::isnan_Float4,
+    BuiltInName::isnan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpIsnan,
+    true);
+constexpr const TFunction kFunction_isinf_0B(
+    BuiltInId::isinf_Float1,
+    BuiltInName::isinf,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpIsinf,
+    true);
+constexpr const TFunction kFunction_isinf_1B(
+    BuiltInId::isinf_Float2,
+    BuiltInName::isinf,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpIsinf,
+    true);
+constexpr const TFunction kFunction_isinf_2B(
+    BuiltInId::isinf_Float3,
+    BuiltInName::isinf,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpIsinf,
+    true);
+constexpr const TFunction kFunction_isinf_3B(
+    BuiltInId::isinf_Float4,
+    BuiltInName::isinf,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpIsinf,
+    true);
+constexpr const TFunction kFunction_floatBitsToInt_0B(
+    BuiltInId::floatBitsToInt_Float1,
+    BuiltInName::floatBitsToInt,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpFloatBitsToInt,
+    true);
+constexpr const TFunction kFunction_floatBitsToInt_1B(
+    BuiltInId::floatBitsToInt_Float2,
+    BuiltInName::floatBitsToInt,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpFloatBitsToInt,
+    true);
+constexpr const TFunction kFunction_floatBitsToInt_2B(
+    BuiltInId::floatBitsToInt_Float3,
+    BuiltInName::floatBitsToInt,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpFloatBitsToInt,
+    true);
+constexpr const TFunction kFunction_floatBitsToInt_3B(
+    BuiltInId::floatBitsToInt_Float4,
+    BuiltInName::floatBitsToInt,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpFloatBitsToInt,
+    true);
+constexpr const TFunction kFunction_floatBitsToUint_0B(
+    BuiltInId::floatBitsToUint_Float1,
+    BuiltInName::floatBitsToUint,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpFloatBitsToUint,
+    true);
+constexpr const TFunction kFunction_floatBitsToUint_1B(
+    BuiltInId::floatBitsToUint_Float2,
+    BuiltInName::floatBitsToUint,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpFloatBitsToUint,
+    true);
+constexpr const TFunction kFunction_floatBitsToUint_2B(
+    BuiltInId::floatBitsToUint_Float3,
+    BuiltInName::floatBitsToUint,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpFloatBitsToUint,
+    true);
+constexpr const TFunction kFunction_floatBitsToUint_3B(
+    BuiltInId::floatBitsToUint_Float4,
+    BuiltInName::floatBitsToUint,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpFloatBitsToUint,
+    true);
+constexpr const TFunction kFunction_intBitsToFloat_0C(
+    BuiltInId::intBitsToFloat_Int1,
+    BuiltInName::intBitsToFloat,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0C0C_o_0C_o_0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpIntBitsToFloat,
+    true);
+constexpr const TFunction kFunction_intBitsToFloat_1C(
+    BuiltInId::intBitsToFloat_Int2,
+    BuiltInName::intBitsToFloat,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C1C0C0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpIntBitsToFloat,
+    true);
+constexpr const TFunction kFunction_intBitsToFloat_2C(
+    BuiltInId::intBitsToFloat_Int3,
+    BuiltInName::intBitsToFloat,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C2C0C0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpIntBitsToFloat,
+    true);
+constexpr const TFunction kFunction_intBitsToFloat_3C(
+    BuiltInId::intBitsToFloat_Int4,
+    BuiltInName::intBitsToFloat,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C0C0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpIntBitsToFloat,
+    true);
+constexpr const TFunction kFunction_uintBitsToFloat_0D(
+    BuiltInId::uintBitsToFloat_UInt1,
+    BuiltInName::uintBitsToFloat,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0C0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpUintBitsToFloat,
+    true);
+constexpr const TFunction kFunction_uintBitsToFloat_1D(
+    BuiltInId::uintBitsToFloat_UInt2,
+    BuiltInName::uintBitsToFloat,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D0C0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpUintBitsToFloat,
+    true);
+constexpr const TFunction kFunction_uintBitsToFloat_2D(
+    BuiltInId::uintBitsToFloat_UInt3,
+    BuiltInName::uintBitsToFloat,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D0C0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpUintBitsToFloat,
+    true);
+constexpr const TFunction kFunction_uintBitsToFloat_3D(
+    BuiltInId::uintBitsToFloat_UInt4,
+    BuiltInName::uintBitsToFloat,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D0C0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpUintBitsToFloat,
+    true);
+constexpr const TFunction kFunction_frexp_0B0C(
+    BuiltInId::frexp_Float1_Int1,
+    BuiltInName::frexp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B_o_0C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpFrexp,
+    false);
+constexpr const TFunction kFunction_frexp_1B1C(
+    BuiltInId::frexp_Float2_Int2,
+    BuiltInName::frexp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B_o_1C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpFrexp,
+    false);
+constexpr const TFunction kFunction_frexp_2B2C(
+    BuiltInId::frexp_Float3_Int3,
+    BuiltInName::frexp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B_o_2C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpFrexp,
+    false);
+constexpr const TFunction kFunction_frexp_3B3C(
+    BuiltInId::frexp_Float4_Int4,
+    BuiltInName::frexp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B_o_3C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpFrexp,
+    false);
+constexpr const TFunction kFunction_ldexp_0B0C(
+    BuiltInId::ldexp_Float1_Int1,
+    BuiltInName::ldexp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpLdexp,
+    true);
+constexpr const TFunction kFunction_ldexp_1B1C(
+    BuiltInId::ldexp_Float2_Int2,
+    BuiltInName::ldexp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpLdexp,
+    true);
+constexpr const TFunction kFunction_ldexp_2B2C(
+    BuiltInId::ldexp_Float3_Int3,
+    BuiltInName::ldexp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpLdexp,
+    true);
+constexpr const TFunction kFunction_ldexp_3B3C(
+    BuiltInId::ldexp_Float4_Int4,
+    BuiltInName::ldexp,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpLdexp,
+    true);
+constexpr const TFunction kFunction_packSnorm2x16_1B(
+    BuiltInId::packSnorm2x16_Float2,
+    BuiltInName::packSnorm2x16,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpPackSnorm2x16,
+    true);
+constexpr const TFunction kFunction_packUnorm2x16_1B(
+    BuiltInId::packUnorm2x16_Float2,
+    BuiltInName::packUnorm2x16,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpPackUnorm2x16,
+    true);
+constexpr const TFunction kFunction_packHalf2x16_1B(
+    BuiltInId::packHalf2x16_Float2,
+    BuiltInName::packHalf2x16,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpPackHalf2x16,
+    true);
+constexpr const TFunction kFunction_unpackSnorm2x16_0D(
+    BuiltInId::unpackSnorm2x16_UInt1,
+    BuiltInName::unpackSnorm2x16,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0C0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpUnpackSnorm2x16,
+    true);
+constexpr const TFunction kFunction_unpackUnorm2x16_0D(
+    BuiltInId::unpackUnorm2x16_UInt1,
+    BuiltInName::unpackUnorm2x16,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0C0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpUnpackUnorm2x16,
+    true);
+constexpr const TFunction kFunction_unpackHalf2x16_0D(
+    BuiltInId::unpackHalf2x16_UInt1,
+    BuiltInName::unpackHalf2x16,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0C0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpUnpackHalf2x16,
+    true);
+constexpr const TFunction kFunction_packUnorm4x8_3B(
+    BuiltInId::packUnorm4x8_Float4,
+    BuiltInName::packUnorm4x8,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpPackUnorm4x8,
+    true);
+constexpr const TFunction kFunction_packSnorm4x8_3B(
+    BuiltInId::packSnorm4x8_Float4,
+    BuiltInName::packSnorm4x8,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpPackSnorm4x8,
+    true);
+constexpr const TFunction kFunction_unpackUnorm4x8_0D(
+    BuiltInId::unpackUnorm4x8_UInt1,
+    BuiltInName::unpackUnorm4x8,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0C0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpUnpackUnorm4x8,
+    true);
+constexpr const TFunction kFunction_unpackSnorm4x8_0D(
+    BuiltInId::unpackSnorm4x8_UInt1,
+    BuiltInName::unpackSnorm4x8,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0C0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpUnpackSnorm4x8,
+    true);
+constexpr const TFunction kFunction_length_0B(
+    BuiltInId::length_Float1,
+    BuiltInName::length,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpLength,
+    true);
+constexpr const TFunction kFunction_length_1B(
+    BuiltInId::length_Float2,
+    BuiltInName::length,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpLength,
+    true);
+constexpr const TFunction kFunction_length_2B(
+    BuiltInId::length_Float3,
+    BuiltInName::length,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpLength,
+    true);
+constexpr const TFunction kFunction_length_3B(
+    BuiltInId::length_Float4,
+    BuiltInName::length,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpLength,
+    true);
+constexpr const TFunction kFunction_distance_0B0B(
+    BuiltInId::distance_Float1_Float1,
+    BuiltInName::distance,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B1B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpDistance,
+    true);
+constexpr const TFunction kFunction_distance_1B1B(
+    BuiltInId::distance_Float2_Float2,
+    BuiltInName::distance,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpDistance,
+    true);
+constexpr const TFunction kFunction_distance_2B2B(
+    BuiltInId::distance_Float3_Float3,
+    BuiltInName::distance,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpDistance,
+    true);
+constexpr const TFunction kFunction_distance_3B3B(
+    BuiltInId::distance_Float4_Float4,
+    BuiltInName::distance,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpDistance,
+    true);
+constexpr const TFunction kFunction_dot_0B0B(
+    BuiltInId::dot_Float1_Float1,
+    BuiltInName::dot,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B1B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpDot,
+    true);
+constexpr const TFunction kFunction_dot_1B1B(
+    BuiltInId::dot_Float2_Float2,
+    BuiltInName::dot,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpDot,
+    true);
+constexpr const TFunction kFunction_dot_2B2B(
+    BuiltInId::dot_Float3_Float3,
+    BuiltInName::dot,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpDot,
+    true);
+constexpr const TFunction kFunction_dot_3B3B(
+    BuiltInId::dot_Float4_Float4,
+    BuiltInName::dot,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpDot,
+    true);
+constexpr const TFunction kFunction_cross_2B2B(
+    BuiltInId::cross_Float3_Float3,
+    BuiltInName::cross,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCross,
+    true);
+constexpr const TFunction kFunction_normalize_0B(
+    BuiltInId::normalize_Float1,
+    BuiltInName::normalize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpNormalize,
+    true);
+constexpr const TFunction kFunction_normalize_1B(
+    BuiltInId::normalize_Float2,
+    BuiltInName::normalize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpNormalize,
+    true);
+constexpr const TFunction kFunction_normalize_2B(
+    BuiltInId::normalize_Float3,
+    BuiltInName::normalize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpNormalize,
+    true);
+constexpr const TFunction kFunction_normalize_3B(
+    BuiltInId::normalize_Float4,
+    BuiltInName::normalize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpNormalize,
+    true);
+constexpr const TFunction kFunction_faceforward_0B0B0B(
+    BuiltInId::faceforward_Float1_Float1_Float1,
+    BuiltInName::faceforward,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpFaceforward,
+    true);
+constexpr const TFunction kFunction_faceforward_1B1B1B(
+    BuiltInId::faceforward_Float2_Float2_Float2,
+    BuiltInName::faceforward,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B1B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpFaceforward,
+    true);
+constexpr const TFunction kFunction_faceforward_2B2B2B(
+    BuiltInId::faceforward_Float3_Float3_Float3,
+    BuiltInName::faceforward,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B2B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpFaceforward,
+    true);
+constexpr const TFunction kFunction_faceforward_3B3B3B(
+    BuiltInId::faceforward_Float4_Float4_Float4,
+    BuiltInName::faceforward,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpFaceforward,
+    true);
+constexpr const TFunction kFunction_reflect_0B0B(
+    BuiltInId::reflect_Float1_Float1,
+    BuiltInName::reflect,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B1B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpReflect,
+    true);
+constexpr const TFunction kFunction_reflect_1B1B(
+    BuiltInId::reflect_Float2_Float2,
+    BuiltInName::reflect,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpReflect,
+    true);
+constexpr const TFunction kFunction_reflect_2B2B(
+    BuiltInId::reflect_Float3_Float3,
+    BuiltInName::reflect,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpReflect,
+    true);
+constexpr const TFunction kFunction_reflect_3B3B(
+    BuiltInId::reflect_Float4_Float4,
+    BuiltInName::reflect,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpReflect,
+    true);
+constexpr const TFunction kFunction_refract_0B0B0B(
+    BuiltInId::refract_Float1_Float1_Float1,
+    BuiltInName::refract,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpRefract,
+    true);
+constexpr const TFunction kFunction_refract_1B1B0B(
+    BuiltInId::refract_Float2_Float2_Float1,
+    BuiltInName::refract,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpRefract,
+    true);
+constexpr const TFunction kFunction_refract_2B2B0B(
+    BuiltInId::refract_Float3_Float3_Float1,
+    BuiltInName::refract,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpRefract,
+    true);
+constexpr const TFunction kFunction_refract_3B3B0B(
+    BuiltInId::refract_Float4_Float4_Float1,
+    BuiltInName::refract,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpRefract,
+    true);
+constexpr const TFunction kFunction_matrixCompMult_5B5B(
+    BuiltInId::matrixCompMult_Float2x2_Float2x2,
+    BuiltInName::matrixCompMult,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p5B5B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 2>(),
+    EOpMulMatrixComponentWise,
+    true);
+constexpr const TFunction kFunction_matrixCompMult_ABAB(
+    BuiltInId::matrixCompMult_Float3x3_Float3x3,
+    BuiltInName::matrixCompMult,
+    TExtension::UNDEFINED,
+    BuiltInParameters::pABAB,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 3>(),
+    EOpMulMatrixComponentWise,
+    true);
+constexpr const TFunction kFunction_matrixCompMult_FBFB(
+    BuiltInId::matrixCompMult_Float4x4_Float4x4,
+    BuiltInName::matrixCompMult,
+    TExtension::UNDEFINED,
+    BuiltInParameters::pFBFB,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 4>(),
+    EOpMulMatrixComponentWise,
+    true);
+constexpr const TFunction kFunction_matrixCompMult_9B9B(
+    BuiltInId::matrixCompMult_Float2x3_Float2x3,
+    BuiltInName::matrixCompMult,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p9B9B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 3>(),
+    EOpMulMatrixComponentWise,
+    true);
+constexpr const TFunction kFunction_matrixCompMult_6B6B(
+    BuiltInId::matrixCompMult_Float3x2_Float3x2,
+    BuiltInName::matrixCompMult,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p6B6B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 2>(),
+    EOpMulMatrixComponentWise,
+    true);
+constexpr const TFunction kFunction_matrixCompMult_DBDB(
+    BuiltInId::matrixCompMult_Float2x4_Float2x4,
+    BuiltInName::matrixCompMult,
+    TExtension::UNDEFINED,
+    BuiltInParameters::pDBDB,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 4>(),
+    EOpMulMatrixComponentWise,
+    true);
+constexpr const TFunction kFunction_matrixCompMult_7B7B(
+    BuiltInId::matrixCompMult_Float4x2_Float4x2,
+    BuiltInName::matrixCompMult,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p7B7B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 2>(),
+    EOpMulMatrixComponentWise,
+    true);
+constexpr const TFunction kFunction_matrixCompMult_EBEB(
+    BuiltInId::matrixCompMult_Float3x4_Float3x4,
+    BuiltInName::matrixCompMult,
+    TExtension::UNDEFINED,
+    BuiltInParameters::pEBEB,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 4>(),
+    EOpMulMatrixComponentWise,
+    true);
+constexpr const TFunction kFunction_matrixCompMult_BBBB(
+    BuiltInId::matrixCompMult_Float4x3_Float4x3,
+    BuiltInName::matrixCompMult,
+    TExtension::UNDEFINED,
+    BuiltInParameters::pBBBB,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 3>(),
+    EOpMulMatrixComponentWise,
+    true);
+constexpr const TFunction kFunction_outerProduct_1B1B(
+    BuiltInId::outerProduct_Float2_Float2,
+    BuiltInName::outerProduct,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 2>(),
+    EOpOuterProduct,
+    true);
+constexpr const TFunction kFunction_outerProduct_2B2B(
+    BuiltInId::outerProduct_Float3_Float3,
+    BuiltInName::outerProduct,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 3>(),
+    EOpOuterProduct,
+    true);
+constexpr const TFunction kFunction_outerProduct_3B3B(
+    BuiltInId::outerProduct_Float4_Float4,
+    BuiltInName::outerProduct,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 4>(),
+    EOpOuterProduct,
+    true);
+constexpr const TFunction kFunction_outerProduct_2B1B(
+    BuiltInId::outerProduct_Float3_Float2,
+    BuiltInName::outerProduct,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B1B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 3>(),
+    EOpOuterProduct,
+    true);
+constexpr const TFunction kFunction_outerProduct_1B2B(
+    BuiltInId::outerProduct_Float2_Float3,
+    BuiltInName::outerProduct,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B2B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 2>(),
+    EOpOuterProduct,
+    true);
+constexpr const TFunction kFunction_outerProduct_3B1B(
+    BuiltInId::outerProduct_Float4_Float2,
+    BuiltInName::outerProduct,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 4>(),
+    EOpOuterProduct,
+    true);
+constexpr const TFunction kFunction_outerProduct_1B3B(
+    BuiltInId::outerProduct_Float2_Float4,
+    BuiltInName::outerProduct,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 2>(),
+    EOpOuterProduct,
+    true);
+constexpr const TFunction kFunction_outerProduct_3B2B(
+    BuiltInId::outerProduct_Float4_Float3,
+    BuiltInName::outerProduct,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B2B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 4>(),
+    EOpOuterProduct,
+    true);
+constexpr const TFunction kFunction_outerProduct_2B3B(
+    BuiltInId::outerProduct_Float3_Float4,
+    BuiltInName::outerProduct,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 3>(),
+    EOpOuterProduct,
+    true);
+constexpr const TFunction kFunction_transpose_5B(
+    BuiltInId::transpose_Float2x2,
+    BuiltInName::transpose,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p5B5B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 2>(),
+    EOpTranspose,
+    true);
+constexpr const TFunction kFunction_transpose_AB(
+    BuiltInId::transpose_Float3x3,
+    BuiltInName::transpose,
+    TExtension::UNDEFINED,
+    BuiltInParameters::pABAB,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 3>(),
+    EOpTranspose,
+    true);
+constexpr const TFunction kFunction_transpose_FB(
+    BuiltInId::transpose_Float4x4,
+    BuiltInName::transpose,
+    TExtension::UNDEFINED,
+    BuiltInParameters::pFBFB,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 4>(),
+    EOpTranspose,
+    true);
+constexpr const TFunction kFunction_transpose_6B(
+    BuiltInId::transpose_Float3x2,
+    BuiltInName::transpose,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p6B6B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 3>(),
+    EOpTranspose,
+    true);
+constexpr const TFunction kFunction_transpose_9B(
+    BuiltInId::transpose_Float2x3,
+    BuiltInName::transpose,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p9B9B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 2>(),
+    EOpTranspose,
+    true);
+constexpr const TFunction kFunction_transpose_7B(
+    BuiltInId::transpose_Float4x2,
+    BuiltInName::transpose,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p7B7B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 4>(),
+    EOpTranspose,
+    true);
+constexpr const TFunction kFunction_transpose_DB(
+    BuiltInId::transpose_Float2x4,
+    BuiltInName::transpose,
+    TExtension::UNDEFINED,
+    BuiltInParameters::pDBDB,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 2>(),
+    EOpTranspose,
+    true);
+constexpr const TFunction kFunction_transpose_BB(
+    BuiltInId::transpose_Float4x3,
+    BuiltInName::transpose,
+    TExtension::UNDEFINED,
+    BuiltInParameters::pBBBB,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 4>(),
+    EOpTranspose,
+    true);
+constexpr const TFunction kFunction_transpose_EB(
+    BuiltInId::transpose_Float3x4,
+    BuiltInName::transpose,
+    TExtension::UNDEFINED,
+    BuiltInParameters::pEBEB,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 3>(),
+    EOpTranspose,
+    true);
+constexpr const TFunction kFunction_determinant_5B(
+    BuiltInId::determinant_Float2x2,
+    BuiltInName::determinant,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p5B5B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpDeterminant,
+    true);
+constexpr const TFunction kFunction_determinant_AB(
+    BuiltInId::determinant_Float3x3,
+    BuiltInName::determinant,
+    TExtension::UNDEFINED,
+    BuiltInParameters::pABAB,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpDeterminant,
+    true);
+constexpr const TFunction kFunction_determinant_FB(
+    BuiltInId::determinant_Float4x4,
+    BuiltInName::determinant,
+    TExtension::UNDEFINED,
+    BuiltInParameters::pFBFB,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpDeterminant,
+    true);
+constexpr const TFunction kFunction_inverse_5B(
+    BuiltInId::inverse_Float2x2,
+    BuiltInName::inverse,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p5B5B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 2>(),
+    EOpInverse,
+    true);
+constexpr const TFunction kFunction_inverse_AB(
+    BuiltInId::inverse_Float3x3,
+    BuiltInName::inverse,
+    TExtension::UNDEFINED,
+    BuiltInParameters::pABAB,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 3>(),
+    EOpInverse,
+    true);
+constexpr const TFunction kFunction_inverse_FB(
+    BuiltInId::inverse_Float4x4,
+    BuiltInName::inverse,
+    TExtension::UNDEFINED,
+    BuiltInParameters::pFBFB,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 4>(),
+    EOpInverse,
+    true);
+constexpr const TFunction kFunction_lessThan_1B1B(
+    BuiltInId::lessThan_Float2_Float2,
+    BuiltInName::lessThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpLessThanComponentWise,
+    true);
+constexpr const TFunction kFunction_lessThan_2B2B(
+    BuiltInId::lessThan_Float3_Float3,
+    BuiltInName::lessThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpLessThanComponentWise,
+    true);
+constexpr const TFunction kFunction_lessThan_3B3B(
+    BuiltInId::lessThan_Float4_Float4,
+    BuiltInName::lessThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpLessThanComponentWise,
+    true);
+constexpr const TFunction kFunction_lessThan_1C1C(
+    BuiltInId::lessThan_Int2_Int2,
+    BuiltInName::lessThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C1C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpLessThanComponentWise,
+    true);
+constexpr const TFunction kFunction_lessThan_2C2C(
+    BuiltInId::lessThan_Int3_Int3,
+    BuiltInName::lessThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C2C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpLessThanComponentWise,
+    true);
+constexpr const TFunction kFunction_lessThan_3C3C(
+    BuiltInId::lessThan_Int4_Int4,
+    BuiltInName::lessThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C3C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpLessThanComponentWise,
+    true);
+constexpr const TFunction kFunction_lessThan_1D1D(
+    BuiltInId::lessThan_UInt2_UInt2,
+    BuiltInName::lessThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D1D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpLessThanComponentWise,
+    true);
+constexpr const TFunction kFunction_lessThan_2D2D(
+    BuiltInId::lessThan_UInt3_UInt3,
+    BuiltInName::lessThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpLessThanComponentWise,
+    true);
+constexpr const TFunction kFunction_lessThan_3D3D(
+    BuiltInId::lessThan_UInt4_UInt4,
+    BuiltInName::lessThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D3D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpLessThanComponentWise,
+    true);
+constexpr const TFunction kFunction_lessThanEqual_1B1B(
+    BuiltInId::lessThanEqual_Float2_Float2,
+    BuiltInName::lessThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpLessThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_lessThanEqual_2B2B(
+    BuiltInId::lessThanEqual_Float3_Float3,
+    BuiltInName::lessThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpLessThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_lessThanEqual_3B3B(
+    BuiltInId::lessThanEqual_Float4_Float4,
+    BuiltInName::lessThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpLessThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_lessThanEqual_1C1C(
+    BuiltInId::lessThanEqual_Int2_Int2,
+    BuiltInName::lessThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C1C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpLessThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_lessThanEqual_2C2C(
+    BuiltInId::lessThanEqual_Int3_Int3,
+    BuiltInName::lessThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C2C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpLessThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_lessThanEqual_3C3C(
+    BuiltInId::lessThanEqual_Int4_Int4,
+    BuiltInName::lessThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C3C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpLessThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_lessThanEqual_1D1D(
+    BuiltInId::lessThanEqual_UInt2_UInt2,
+    BuiltInName::lessThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D1D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpLessThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_lessThanEqual_2D2D(
+    BuiltInId::lessThanEqual_UInt3_UInt3,
+    BuiltInName::lessThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpLessThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_lessThanEqual_3D3D(
+    BuiltInId::lessThanEqual_UInt4_UInt4,
+    BuiltInName::lessThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D3D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpLessThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThan_1B1B(
+    BuiltInId::greaterThan_Float2_Float2,
+    BuiltInName::greaterThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpGreaterThanComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThan_2B2B(
+    BuiltInId::greaterThan_Float3_Float3,
+    BuiltInName::greaterThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpGreaterThanComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThan_3B3B(
+    BuiltInId::greaterThan_Float4_Float4,
+    BuiltInName::greaterThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpGreaterThanComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThan_1C1C(
+    BuiltInId::greaterThan_Int2_Int2,
+    BuiltInName::greaterThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C1C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpGreaterThanComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThan_2C2C(
+    BuiltInId::greaterThan_Int3_Int3,
+    BuiltInName::greaterThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C2C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpGreaterThanComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThan_3C3C(
+    BuiltInId::greaterThan_Int4_Int4,
+    BuiltInName::greaterThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C3C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpGreaterThanComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThan_1D1D(
+    BuiltInId::greaterThan_UInt2_UInt2,
+    BuiltInName::greaterThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D1D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpGreaterThanComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThan_2D2D(
+    BuiltInId::greaterThan_UInt3_UInt3,
+    BuiltInName::greaterThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpGreaterThanComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThan_3D3D(
+    BuiltInId::greaterThan_UInt4_UInt4,
+    BuiltInName::greaterThan,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D3D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpGreaterThanComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThanEqual_1B1B(
+    BuiltInId::greaterThanEqual_Float2_Float2,
+    BuiltInName::greaterThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpGreaterThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThanEqual_2B2B(
+    BuiltInId::greaterThanEqual_Float3_Float3,
+    BuiltInName::greaterThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpGreaterThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThanEqual_3B3B(
+    BuiltInId::greaterThanEqual_Float4_Float4,
+    BuiltInName::greaterThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpGreaterThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThanEqual_1C1C(
+    BuiltInId::greaterThanEqual_Int2_Int2,
+    BuiltInName::greaterThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C1C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpGreaterThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThanEqual_2C2C(
+    BuiltInId::greaterThanEqual_Int3_Int3,
+    BuiltInName::greaterThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C2C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpGreaterThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThanEqual_3C3C(
+    BuiltInId::greaterThanEqual_Int4_Int4,
+    BuiltInName::greaterThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C3C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpGreaterThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThanEqual_1D1D(
+    BuiltInId::greaterThanEqual_UInt2_UInt2,
+    BuiltInName::greaterThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D1D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpGreaterThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThanEqual_2D2D(
+    BuiltInId::greaterThanEqual_UInt3_UInt3,
+    BuiltInName::greaterThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpGreaterThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_greaterThanEqual_3D3D(
+    BuiltInId::greaterThanEqual_UInt4_UInt4,
+    BuiltInName::greaterThanEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D3D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpGreaterThanEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_equal_1B1B(
+    BuiltInId::equal_Float2_Float2,
+    BuiltInName::equal,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_equal_2B2B(
+    BuiltInId::equal_Float3_Float3,
+    BuiltInName::equal,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_equal_3B3B(
+    BuiltInId::equal_Float4_Float4,
+    BuiltInName::equal,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_equal_1C1C(
+    BuiltInId::equal_Int2_Int2,
+    BuiltInName::equal,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C1C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_equal_2C2C(
+    BuiltInId::equal_Int3_Int3,
+    BuiltInName::equal,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C2C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_equal_3C3C(
+    BuiltInId::equal_Int4_Int4,
+    BuiltInName::equal,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C3C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_equal_1D1D(
+    BuiltInId::equal_UInt2_UInt2,
+    BuiltInName::equal,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D1D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_equal_2D2D(
+    BuiltInId::equal_UInt3_UInt3,
+    BuiltInName::equal,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_equal_3D3D(
+    BuiltInId::equal_UInt4_UInt4,
+    BuiltInName::equal,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D3D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_equal_1E1E(
+    BuiltInId::equal_Bool2_Bool2,
+    BuiltInName::equal,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1E1E,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_equal_2E2E(
+    BuiltInId::equal_Bool3_Bool3,
+    BuiltInName::equal,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2E2E,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_equal_3E3E(
+    BuiltInId::equal_Bool4_Bool4,
+    BuiltInName::equal,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3E3E,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_notEqual_1B1B(
+    BuiltInId::notEqual_Float2_Float2,
+    BuiltInName::notEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpNotEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_notEqual_2B2B(
+    BuiltInId::notEqual_Float3_Float3,
+    BuiltInName::notEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2B0B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpNotEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_notEqual_3B3B(
+    BuiltInId::notEqual_Float4_Float4,
+    BuiltInName::notEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B3B3B,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpNotEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_notEqual_1C1C(
+    BuiltInId::notEqual_Int2_Int2,
+    BuiltInName::notEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C1C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpNotEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_notEqual_2C2C(
+    BuiltInId::notEqual_Int3_Int3,
+    BuiltInName::notEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C2C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpNotEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_notEqual_3C3C(
+    BuiltInId::notEqual_Int4_Int4,
+    BuiltInName::notEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C3C0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpNotEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_notEqual_1D1D(
+    BuiltInId::notEqual_UInt2_UInt2,
+    BuiltInName::notEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D1D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpNotEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_notEqual_2D2D(
+    BuiltInId::notEqual_UInt3_UInt3,
+    BuiltInName::notEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpNotEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_notEqual_3D3D(
+    BuiltInId::notEqual_UInt4_UInt4,
+    BuiltInName::notEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D3D0C0C,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpNotEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_notEqual_1E1E(
+    BuiltInId::notEqual_Bool2_Bool2,
+    BuiltInName::notEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1E1E,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpNotEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_notEqual_2E2E(
+    BuiltInId::notEqual_Bool3_Bool3,
+    BuiltInName::notEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2E2E,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpNotEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_notEqual_3E3E(
+    BuiltInId::notEqual_Bool4_Bool4,
+    BuiltInName::notEqual,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3E3E,
+    2,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpNotEqualComponentWise,
+    true);
+constexpr const TFunction kFunction_any_1E(
+    BuiltInId::any_Bool2,
+    BuiltInName::any,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1E1E,
+    1,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpAny,
+    true);
+constexpr const TFunction kFunction_any_2E(
+    BuiltInId::any_Bool3,
+    BuiltInName::any,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2E2E,
+    1,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpAny,
+    true);
+constexpr const TFunction kFunction_any_3E(
+    BuiltInId::any_Bool4,
+    BuiltInName::any,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3E3E,
+    1,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpAny,
+    true);
+constexpr const TFunction kFunction_all_1E(
+    BuiltInId::all_Bool2,
+    BuiltInName::all,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1E1E,
+    1,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpAll,
+    true);
+constexpr const TFunction kFunction_all_2E(
+    BuiltInId::all_Bool3,
+    BuiltInName::all,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2E2E,
+    1,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpAll,
+    true);
+constexpr const TFunction kFunction_all_3E(
+    BuiltInId::all_Bool4,
+    BuiltInName::all,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3E3E,
+    1,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpAll,
+    true);
+constexpr const TFunction kFunction_notFunc_1E(
+    BuiltInId::notFunc_Bool2,
+    BuiltInName::notFunc,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1E1E,
+    1,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpLogicalNotComponentWise,
+    true);
+constexpr const TFunction kFunction_notFunc_2E(
+    BuiltInId::notFunc_Bool3,
+    BuiltInName::notFunc,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2E2E,
+    1,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpLogicalNotComponentWise,
+    true);
+constexpr const TFunction kFunction_notFunc_3E(
+    BuiltInId::notFunc_Bool4,
+    BuiltInName::notFunc,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3E3E,
+    1,
+    StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpLogicalNotComponentWise,
+    true);
+constexpr const TFunction kFunction_bitfieldExtract_0C0C0C(
+    BuiltInId::bitfieldExtract_Int1_Int1_Int1,
+    BuiltInName::bitfieldExtract,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0C0C0C0C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpBitfieldExtract,
+    true);
+constexpr const TFunction kFunction_bitfieldExtract_1C0C0C(
+    BuiltInId::bitfieldExtract_Int2_Int1_Int1,
+    BuiltInName::bitfieldExtract,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C0C0C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpBitfieldExtract,
+    true);
+constexpr const TFunction kFunction_bitfieldExtract_2C0C0C(
+    BuiltInId::bitfieldExtract_Int3_Int1_Int1,
+    BuiltInName::bitfieldExtract,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C0C0C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpBitfieldExtract,
+    true);
+constexpr const TFunction kFunction_bitfieldExtract_3C0C0C(
+    BuiltInId::bitfieldExtract_Int4_Int1_Int1,
+    BuiltInName::bitfieldExtract,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C0C0C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpBitfieldExtract,
+    true);
+constexpr const TFunction kFunction_bitfieldExtract_0D0C0C(
+    BuiltInId::bitfieldExtract_UInt1_Int1_Int1,
+    BuiltInName::bitfieldExtract,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0C0C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpBitfieldExtract,
+    true);
+constexpr const TFunction kFunction_bitfieldExtract_1D0C0C(
+    BuiltInId::bitfieldExtract_UInt2_Int1_Int1,
+    BuiltInName::bitfieldExtract,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D0C0C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpBitfieldExtract,
+    true);
+constexpr const TFunction kFunction_bitfieldExtract_2D0C0C(
+    BuiltInId::bitfieldExtract_UInt3_Int1_Int1,
+    BuiltInName::bitfieldExtract,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D0C0C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpBitfieldExtract,
+    true);
+constexpr const TFunction kFunction_bitfieldExtract_3D0C0C(
+    BuiltInId::bitfieldExtract_UInt4_Int1_Int1,
+    BuiltInName::bitfieldExtract,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D0C0C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpBitfieldExtract,
+    true);
+constexpr const TFunction kFunction_bitfieldInsert_0C0C0C0C(
+    BuiltInId::bitfieldInsert_Int1_Int1_Int1_Int1,
+    BuiltInName::bitfieldInsert,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0C0C0C0C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpBitfieldInsert,
+    true);
+constexpr const TFunction kFunction_bitfieldInsert_1C1C0C0C(
+    BuiltInId::bitfieldInsert_Int2_Int2_Int1_Int1,
+    BuiltInName::bitfieldInsert,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C1C0C0C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpBitfieldInsert,
+    true);
+constexpr const TFunction kFunction_bitfieldInsert_2C2C0C0C(
+    BuiltInId::bitfieldInsert_Int3_Int3_Int1_Int1,
+    BuiltInName::bitfieldInsert,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C2C0C0C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpBitfieldInsert,
+    true);
+constexpr const TFunction kFunction_bitfieldInsert_3C3C0C0C(
+    BuiltInId::bitfieldInsert_Int4_Int4_Int1_Int1,
+    BuiltInName::bitfieldInsert,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C3C0C0C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpBitfieldInsert,
+    true);
+constexpr const TFunction kFunction_bitfieldInsert_0D0D0C0C(
+    BuiltInId::bitfieldInsert_UInt1_UInt1_Int1_Int1,
+    BuiltInName::bitfieldInsert,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0D0C0C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpBitfieldInsert,
+    true);
+constexpr const TFunction kFunction_bitfieldInsert_1D1D0C0C(
+    BuiltInId::bitfieldInsert_UInt2_UInt2_Int1_Int1,
+    BuiltInName::bitfieldInsert,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D1D0C0C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpBitfieldInsert,
+    true);
+constexpr const TFunction kFunction_bitfieldInsert_2D2D0C0C(
+    BuiltInId::bitfieldInsert_UInt3_UInt3_Int1_Int1,
+    BuiltInName::bitfieldInsert,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D0C0C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpBitfieldInsert,
+    true);
+constexpr const TFunction kFunction_bitfieldInsert_3D3D0C0C(
+    BuiltInId::bitfieldInsert_UInt4_UInt4_Int1_Int1,
+    BuiltInName::bitfieldInsert,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D3D0C0C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpBitfieldInsert,
+    true);
+constexpr const TFunction kFunction_bitfieldReverse_0C(
+    BuiltInId::bitfieldReverse_Int1,
+    BuiltInName::bitfieldReverse,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0C0C_o_0C_o_0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpBitfieldReverse,
+    true);
+constexpr const TFunction kFunction_bitfieldReverse_1C(
+    BuiltInId::bitfieldReverse_Int2,
+    BuiltInName::bitfieldReverse,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C1C0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpBitfieldReverse,
+    true);
+constexpr const TFunction kFunction_bitfieldReverse_2C(
+    BuiltInId::bitfieldReverse_Int3,
+    BuiltInName::bitfieldReverse,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C2C0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpBitfieldReverse,
+    true);
+constexpr const TFunction kFunction_bitfieldReverse_3C(
+    BuiltInId::bitfieldReverse_Int4,
+    BuiltInName::bitfieldReverse,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpBitfieldReverse,
+    true);
+constexpr const TFunction kFunction_bitfieldReverse_0D(
+    BuiltInId::bitfieldReverse_UInt1,
+    BuiltInName::bitfieldReverse,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0C0C,
+    1,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpBitfieldReverse,
+    true);
+constexpr const TFunction kFunction_bitfieldReverse_1D(
+    BuiltInId::bitfieldReverse_UInt2,
+    BuiltInName::bitfieldReverse,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D0C0C,
+    1,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpBitfieldReverse,
+    true);
+constexpr const TFunction kFunction_bitfieldReverse_2D(
+    BuiltInId::bitfieldReverse_UInt3,
+    BuiltInName::bitfieldReverse,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D0C0C,
+    1,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpBitfieldReverse,
+    true);
+constexpr const TFunction kFunction_bitfieldReverse_3D(
+    BuiltInId::bitfieldReverse_UInt4,
+    BuiltInName::bitfieldReverse,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D0C0C,
+    1,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpBitfieldReverse,
+    true);
+constexpr const TFunction kFunction_bitCount_0C(
+    BuiltInId::bitCount_Int1,
+    BuiltInName::bitCount,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0C0C_o_0C_o_0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpBitCount,
+    true);
+constexpr const TFunction kFunction_bitCount_1C(
+    BuiltInId::bitCount_Int2,
+    BuiltInName::bitCount,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C1C0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpBitCount,
+    true);
+constexpr const TFunction kFunction_bitCount_2C(
+    BuiltInId::bitCount_Int3,
+    BuiltInName::bitCount,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C2C0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpBitCount,
+    true);
+constexpr const TFunction kFunction_bitCount_3C(
+    BuiltInId::bitCount_Int4,
+    BuiltInName::bitCount,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpBitCount,
+    true);
+constexpr const TFunction kFunction_bitCount_0D(
+    BuiltInId::bitCount_UInt1,
+    BuiltInName::bitCount,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpBitCount,
+    true);
+constexpr const TFunction kFunction_bitCount_1D(
+    BuiltInId::bitCount_UInt2,
+    BuiltInName::bitCount,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpBitCount,
+    true);
+constexpr const TFunction kFunction_bitCount_2D(
+    BuiltInId::bitCount_UInt3,
+    BuiltInName::bitCount,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpBitCount,
+    true);
+constexpr const TFunction kFunction_bitCount_3D(
+    BuiltInId::bitCount_UInt4,
+    BuiltInName::bitCount,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpBitCount,
+    true);
+constexpr const TFunction kFunction_findLSB_0C(
+    BuiltInId::findLSB_Int1,
+    BuiltInName::findLSB,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0C0C_o_0C_o_0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpFindLSB,
+    true);
+constexpr const TFunction kFunction_findLSB_1C(
+    BuiltInId::findLSB_Int2,
+    BuiltInName::findLSB,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C1C0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpFindLSB,
+    true);
+constexpr const TFunction kFunction_findLSB_2C(
+    BuiltInId::findLSB_Int3,
+    BuiltInName::findLSB,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C2C0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpFindLSB,
+    true);
+constexpr const TFunction kFunction_findLSB_3C(
+    BuiltInId::findLSB_Int4,
+    BuiltInName::findLSB,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpFindLSB,
+    true);
+constexpr const TFunction kFunction_findLSB_0D(
+    BuiltInId::findLSB_UInt1,
+    BuiltInName::findLSB,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpFindLSB,
+    true);
+constexpr const TFunction kFunction_findLSB_1D(
+    BuiltInId::findLSB_UInt2,
+    BuiltInName::findLSB,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpFindLSB,
+    true);
+constexpr const TFunction kFunction_findLSB_2D(
+    BuiltInId::findLSB_UInt3,
+    BuiltInName::findLSB,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpFindLSB,
+    true);
+constexpr const TFunction kFunction_findLSB_3D(
+    BuiltInId::findLSB_UInt4,
+    BuiltInName::findLSB,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpFindLSB,
+    true);
+constexpr const TFunction kFunction_findMSB_0C(
+    BuiltInId::findMSB_Int1,
+    BuiltInName::findMSB,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0C0C_o_0C_o_0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpFindMSB,
+    true);
+constexpr const TFunction kFunction_findMSB_1C(
+    BuiltInId::findMSB_Int2,
+    BuiltInName::findMSB,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C1C0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpFindMSB,
+    true);
+constexpr const TFunction kFunction_findMSB_2C(
+    BuiltInId::findMSB_Int3,
+    BuiltInName::findMSB,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C2C0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpFindMSB,
+    true);
+constexpr const TFunction kFunction_findMSB_3C(
+    BuiltInId::findMSB_Int4,
+    BuiltInName::findMSB,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpFindMSB,
+    true);
+constexpr const TFunction kFunction_findMSB_0D(
+    BuiltInId::findMSB_UInt1,
+    BuiltInName::findMSB,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpFindMSB,
+    true);
+constexpr const TFunction kFunction_findMSB_1D(
+    BuiltInId::findMSB_UInt2,
+    BuiltInName::findMSB,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpFindMSB,
+    true);
+constexpr const TFunction kFunction_findMSB_2D(
+    BuiltInId::findMSB_UInt3,
+    BuiltInName::findMSB,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpFindMSB,
+    true);
+constexpr const TFunction kFunction_findMSB_3D(
+    BuiltInId::findMSB_UInt4,
+    BuiltInName::findMSB,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D0C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpFindMSB,
+    true);
+constexpr const TFunction kFunction_uaddCarry_0D0D0D(
+    BuiltInId::uaddCarry_UInt1_UInt1_UInt1,
+    BuiltInName::uaddCarry,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0D_o_0D_o_0D,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpUaddCarry,
+    false);
+constexpr const TFunction kFunction_uaddCarry_1D1D1D(
+    BuiltInId::uaddCarry_UInt2_UInt2_UInt2,
+    BuiltInName::uaddCarry,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D1D_o_1D_o_1D,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpUaddCarry,
+    false);
+constexpr const TFunction kFunction_uaddCarry_2D2D2D(
+    BuiltInId::uaddCarry_UInt3_UInt3_UInt3,
+    BuiltInName::uaddCarry,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D_o_2D_o_2D,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpUaddCarry,
+    false);
+constexpr const TFunction kFunction_uaddCarry_3D3D3D(
+    BuiltInId::uaddCarry_UInt4_UInt4_UInt4,
+    BuiltInName::uaddCarry,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D3D_o_3D_o_3D,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpUaddCarry,
+    false);
+constexpr const TFunction kFunction_usubBorrow_0D0D0D(
+    BuiltInId::usubBorrow_UInt1_UInt1_UInt1,
+    BuiltInName::usubBorrow,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0D_o_0D_o_0D,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpUsubBorrow,
+    false);
+constexpr const TFunction kFunction_usubBorrow_1D1D1D(
+    BuiltInId::usubBorrow_UInt2_UInt2_UInt2,
+    BuiltInName::usubBorrow,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D1D_o_1D_o_1D,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpUsubBorrow,
+    false);
+constexpr const TFunction kFunction_usubBorrow_2D2D2D(
+    BuiltInId::usubBorrow_UInt3_UInt3_UInt3,
+    BuiltInName::usubBorrow,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D_o_2D_o_2D,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpUsubBorrow,
+    false);
+constexpr const TFunction kFunction_usubBorrow_3D3D3D(
+    BuiltInId::usubBorrow_UInt4_UInt4_UInt4,
+    BuiltInName::usubBorrow,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D3D_o_3D_o_3D,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpUsubBorrow,
+    false);
+constexpr const TFunction kFunction_umulExtended_0D0D0D0D(
+    BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+    BuiltInName::umulExtended,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0D0D_o_0D_o_0D,
+    4,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpUmulExtended,
+    false);
+constexpr const TFunction kFunction_umulExtended_1D1D1D1D(
+    BuiltInId::umulExtended_UInt2_UInt2_UInt2_UInt2,
+    BuiltInName::umulExtended,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1D1D_o_1D_o_1D,
+    4,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpUmulExtended,
+    false);
+constexpr const TFunction kFunction_umulExtended_2D2D2D2D(
+    BuiltInId::umulExtended_UInt3_UInt3_UInt3_UInt3,
+    BuiltInName::umulExtended,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2D2D_o_2D_o_2D,
+    4,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpUmulExtended,
+    false);
+constexpr const TFunction kFunction_umulExtended_3D3D3D3D(
+    BuiltInId::umulExtended_UInt4_UInt4_UInt4_UInt4,
+    BuiltInName::umulExtended,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3D3D_o_3D_o_3D,
+    4,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpUmulExtended,
+    false);
+constexpr const TFunction kFunction_imulExtended_0C0C0C0C(
+    BuiltInId::imulExtended_Int1_Int1_Int1_Int1,
+    BuiltInName::imulExtended,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0C0C_o_0C_o_0C,
+    4,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpImulExtended,
+    false);
+constexpr const TFunction kFunction_imulExtended_1C1C1C1C(
+    BuiltInId::imulExtended_Int2_Int2_Int2_Int2,
+    BuiltInName::imulExtended,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1C1C_o_1C_o_1C,
+    4,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpImulExtended,
+    false);
+constexpr const TFunction kFunction_imulExtended_2C2C2C2C(
+    BuiltInId::imulExtended_Int3_Int3_Int3_Int3,
+    BuiltInName::imulExtended,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2C2C_o_2C_o_2C,
+    4,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpImulExtended,
+    false);
+constexpr const TFunction kFunction_imulExtended_3C3C3C3C(
+    BuiltInId::imulExtended_Int4_Int4_Int4_Int4,
+    BuiltInName::imulExtended,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3C3C_o_3C_o_3C,
+    4,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpImulExtended,
+    false);
+constexpr const TFunction kFunction_texture2D_0H1B(
+    BuiltInId::texture2D_Sampler2D1_Float2,
+    BuiltInName::texture2D,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H1B1B1B1C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2DProj_0H2B(
+    BuiltInId::texture2DProj_Sampler2D1_Float3,
+    BuiltInName::texture2DProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H2B0B1C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2DProj_0H3B(
+    BuiltInId::texture2DProj_Sampler2D1_Float4,
+    BuiltInName::texture2DProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H3B0B1C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureCube_0J2B(
+    BuiltInId::textureCube_SamplerCube1_Float3,
+    BuiltInName::textureCube,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0J2B2B2B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2D_0L1B(
+    BuiltInId::texture2D_SamplerExternalOES1_Float2,
+    BuiltInName::texture2D,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0L1B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2DProj_0L2B(
+    BuiltInId::texture2DProj_SamplerExternalOES1_Float3,
+    BuiltInName::texture2DProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0L2B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2DProj_0L3B(
+    BuiltInId::texture2DProj_SamplerExternalOES1_Float4,
+    BuiltInName::texture2DProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0L3B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2DRect_0N1B(
+    BuiltInId::texture2DRect_Sampler2DRect1_Float2,
+    BuiltInName::texture2DRect,
+    TExtension::ARB_texture_rectangle,
+    BuiltInParameters::p0N1B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2DRectProj_0N2B(
+    BuiltInId::texture2DRectProj_Sampler2DRect1_Float3,
+    BuiltInName::texture2DRectProj,
+    TExtension::ARB_texture_rectangle,
+    BuiltInParameters::p0N2B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2DRectProj_0N3B(
+    BuiltInId::texture2DRectProj_Sampler2DRect1_Float4,
+    BuiltInName::texture2DRectProj,
+    TExtension::ARB_texture_rectangle,
+    BuiltInParameters::p0N3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0N1B(
+    BuiltInId::texture_Sampler2DRect1_Float2,
+    BuiltInName::texture,
+    TExtension::ARB_texture_rectangle,
+    BuiltInParameters::p0N1B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0N2B(
+    BuiltInId::textureProj_Sampler2DRect1_Float3,
+    BuiltInName::textureProj,
+    TExtension::ARB_texture_rectangle,
+    BuiltInParameters::p0N2B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0N3B(
+    BuiltInId::textureProj_Sampler2DRect1_Float4,
+    BuiltInName::textureProj,
+    TExtension::ARB_texture_rectangle,
+    BuiltInParameters::p0N3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2DGradEXT_0H1B1B1B(
+    BuiltInId::texture2DGradEXT_Sampler2D1_Float2_Float2_Float2,
+    BuiltInName::texture2DGradEXT,
+    TExtension::EXT_shader_texture_lod,
+    BuiltInParameters::p0H1B1B1B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2DProjGradEXT_0H2B1B1B(
+    BuiltInId::texture2DProjGradEXT_Sampler2D1_Float3_Float2_Float2,
+    BuiltInName::texture2DProjGradEXT,
+    TExtension::EXT_shader_texture_lod,
+    BuiltInParameters::p0H2B1B1B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2DProjGradEXT_0H3B1B1B(
+    BuiltInId::texture2DProjGradEXT_Sampler2D1_Float4_Float2_Float2,
+    BuiltInName::texture2DProjGradEXT,
+    TExtension::EXT_shader_texture_lod,
+    BuiltInParameters::p0H3B1B1B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureCubeGradEXT_0J2B2B2B(
+    BuiltInId::textureCubeGradEXT_SamplerCube1_Float3_Float3_Float3,
+    BuiltInName::textureCubeGradEXT,
+    TExtension::EXT_shader_texture_lod,
+    BuiltInParameters::p0J2B2B2B,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2D_0H1B0B(
+    BuiltInId::texture2D_Sampler2D1_Float2_Float1,
+    BuiltInName::texture2D,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H1B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2DProj_0H2B0B(
+    BuiltInId::texture2DProj_Sampler2D1_Float3_Float1,
+    BuiltInName::texture2DProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H2B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2DProj_0H3B0B(
+    BuiltInId::texture2DProj_Sampler2D1_Float4_Float1,
+    BuiltInName::texture2DProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H3B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureCube_0J2B0B(
+    BuiltInId::textureCube_SamplerCube1_Float3_Float1,
+    BuiltInName::textureCube,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0J2B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_dFdxExt_0B(
+    BuiltInId::dFdxExt_Float1,
+    BuiltInName::dFdxExt,
+    TExtension::OES_standard_derivatives,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpDFdx,
+    false);
+constexpr const TFunction kFunction_dFdxExt_1B(
+    BuiltInId::dFdxExt_Float2,
+    BuiltInName::dFdxExt,
+    TExtension::OES_standard_derivatives,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpDFdx,
+    false);
+constexpr const TFunction kFunction_dFdxExt_2B(
+    BuiltInId::dFdxExt_Float3,
+    BuiltInName::dFdxExt,
+    TExtension::OES_standard_derivatives,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpDFdx,
+    false);
+constexpr const TFunction kFunction_dFdxExt_3B(
+    BuiltInId::dFdxExt_Float4,
+    BuiltInName::dFdxExt,
+    TExtension::OES_standard_derivatives,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpDFdx,
+    false);
+constexpr const TFunction kFunction_dFdyExt_0B(
+    BuiltInId::dFdyExt_Float1,
+    BuiltInName::dFdyExt,
+    TExtension::OES_standard_derivatives,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpDFdy,
+    false);
+constexpr const TFunction kFunction_dFdyExt_1B(
+    BuiltInId::dFdyExt_Float2,
+    BuiltInName::dFdyExt,
+    TExtension::OES_standard_derivatives,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpDFdy,
+    false);
+constexpr const TFunction kFunction_dFdyExt_2B(
+    BuiltInId::dFdyExt_Float3,
+    BuiltInName::dFdyExt,
+    TExtension::OES_standard_derivatives,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpDFdy,
+    false);
+constexpr const TFunction kFunction_dFdyExt_3B(
+    BuiltInId::dFdyExt_Float4,
+    BuiltInName::dFdyExt,
+    TExtension::OES_standard_derivatives,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpDFdy,
+    false);
+constexpr const TFunction kFunction_fwidthExt_0B(
+    BuiltInId::fwidthExt_Float1,
+    BuiltInName::fwidthExt,
+    TExtension::OES_standard_derivatives,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpFwidth,
+    false);
+constexpr const TFunction kFunction_fwidthExt_1B(
+    BuiltInId::fwidthExt_Float2,
+    BuiltInName::fwidthExt,
+    TExtension::OES_standard_derivatives,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpFwidth,
+    false);
+constexpr const TFunction kFunction_fwidthExt_2B(
+    BuiltInId::fwidthExt_Float3,
+    BuiltInName::fwidthExt,
+    TExtension::OES_standard_derivatives,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpFwidth,
+    false);
+constexpr const TFunction kFunction_fwidthExt_3B(
+    BuiltInId::fwidthExt_Float4,
+    BuiltInName::fwidthExt,
+    TExtension::OES_standard_derivatives,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpFwidth,
+    false);
+constexpr const TFunction kFunction_texture2DLodEXT_0H1B0B(
+    BuiltInId::texture2DLodEXT_Sampler2D1_Float2_Float1,
+    BuiltInName::texture2DLodEXT,
+    TExtension::EXT_shader_texture_lod,
+    BuiltInParameters::p0H1B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2DProjLodEXT_0H2B0B(
+    BuiltInId::texture2DProjLodEXT_Sampler2D1_Float3_Float1,
+    BuiltInName::texture2DProjLodEXT,
+    TExtension::EXT_shader_texture_lod,
+    BuiltInParameters::p0H2B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2DProjLodEXT_0H3B0B(
+    BuiltInId::texture2DProjLodEXT_Sampler2D1_Float4_Float1,
+    BuiltInName::texture2DProjLodEXT,
+    TExtension::EXT_shader_texture_lod,
+    BuiltInParameters::p0H3B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureCubeLodEXT_0J2B0B(
+    BuiltInId::textureCubeLodEXT_SamplerCube1_Float3_Float1,
+    BuiltInName::textureCubeLodEXT,
+    TExtension::EXT_shader_texture_lod,
+    BuiltInParameters::p0J2B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2DLod_0H1B0B(
+    BuiltInId::texture2DLod_Sampler2D1_Float2_Float1,
+    BuiltInName::texture2DLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H1B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2DProjLod_0H2B0B(
+    BuiltInId::texture2DProjLod_Sampler2D1_Float3_Float1,
+    BuiltInName::texture2DProjLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H2B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture2DProjLod_0H3B0B(
+    BuiltInId::texture2DProjLod_Sampler2D1_Float4_Float1,
+    BuiltInName::texture2DProjLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H3B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureCubeLod_0J2B0B(
+    BuiltInId::textureCubeLod_SamplerCube1_Float3_Float1,
+    BuiltInName::textureCubeLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0J2B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0H1B(
+    BuiltInId::texture_Sampler2D1_Float2,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H1B1B1B1C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0P1B(
+    BuiltInId::texture_ISampler2D1_Float2,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P1B0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0U1B(
+    BuiltInId::texture_USampler2D1_Float2,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U1B0B1C,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0I2B(
+    BuiltInId::texture_Sampler3D1_Float3,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I2B0B2C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0Q2B(
+    BuiltInId::texture_ISampler3D1_Float3,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q2B0B2C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0V2B(
+    BuiltInId::texture_USampler3D1_Float3,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V2B2B2B2C,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0J2B(
+    BuiltInId::texture_SamplerCube1_Float3,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0J2B2B2B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0R2B(
+    BuiltInId::texture_ISamplerCube1_Float3,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0R2B2B2B,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0W2B(
+    BuiltInId::texture_USamplerCube1_Float3,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0W2B0B,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0K2B(
+    BuiltInId::texture_Sampler2DArray1_Float3,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0K2B0B1C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0S2B(
+    BuiltInId::texture_ISampler2DArray1_Float3,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0S2B0B1C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0X2B(
+    BuiltInId::texture_USampler2DArray1_Float3,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0X2B1C0C,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0H2B(
+    BuiltInId::textureProj_Sampler2D1_Float3,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H2B0B1C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0P2B(
+    BuiltInId::textureProj_ISampler2D1_Float3,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P2B0B1C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0U2B(
+    BuiltInId::textureProj_USampler2D1_Float3,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U2B1B1B1C,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0H3B(
+    BuiltInId::textureProj_Sampler2D1_Float4,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H3B0B1C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0P3B(
+    BuiltInId::textureProj_ISampler2D1_Float4,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P3B0B1C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0U3B(
+    BuiltInId::textureProj_USampler2D1_Float4,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U3B1C0B,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0I3B(
+    BuiltInId::textureProj_Sampler3D1_Float4,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I3B2C0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0Q3B(
+    BuiltInId::textureProj_ISampler3D1_Float4,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q3B0B2C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0V3B(
+    BuiltInId::textureProj_USampler3D1_Float4,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V3B2B2B2C,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLod_0H1B0B(
+    BuiltInId::textureLod_Sampler2D1_Float2_Float1,
+    BuiltInName::textureLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H1B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLod_0P1B0B(
+    BuiltInId::textureLod_ISampler2D1_Float2_Float1,
+    BuiltInName::textureLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P1B0B1C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLod_0U1B0B(
+    BuiltInId::textureLod_USampler2D1_Float2_Float1,
+    BuiltInName::textureLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U1B0B1C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLod_0I2B0B(
+    BuiltInId::textureLod_Sampler3D1_Float3_Float1,
+    BuiltInName::textureLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I2B0B2C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLod_0Q2B0B(
+    BuiltInId::textureLod_ISampler3D1_Float3_Float1,
+    BuiltInName::textureLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q2B0B2C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLod_0V2B0B(
+    BuiltInId::textureLod_USampler3D1_Float3_Float1,
+    BuiltInName::textureLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V2B0B2C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLod_0J2B0B(
+    BuiltInId::textureLod_SamplerCube1_Float3_Float1,
+    BuiltInName::textureLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0J2B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLod_0R2B0B(
+    BuiltInId::textureLod_ISamplerCube1_Float3_Float1,
+    BuiltInName::textureLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0R2B0B,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLod_0W2B0B(
+    BuiltInId::textureLod_USamplerCube1_Float3_Float1,
+    BuiltInName::textureLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0W2B0B,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLod_0K2B0B(
+    BuiltInId::textureLod_Sampler2DArray1_Float3_Float1,
+    BuiltInName::textureLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0K2B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLod_0S2B0B(
+    BuiltInId::textureLod_ISampler2DArray1_Float3_Float1,
+    BuiltInName::textureLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0S2B0B1C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLod_0X2B0B(
+    BuiltInId::textureLod_USampler2DArray1_Float3_Float1,
+    BuiltInName::textureLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0X2B0B1C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0Z2B(
+    BuiltInId::texture_Sampler2DShadow1_Float3,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z2B1B1B1C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0a3B(
+    BuiltInId::texture_SamplerCubeShadow1_Float4,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0a3B2B2B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0b3B(
+    BuiltInId::texture_Sampler2DArrayShadow1_Float4,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0b3B1B1B1C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0Z3B(
+    BuiltInId::textureProj_Sampler2DShadow1_Float4,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z3B0B1C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLod_0Z2B0B(
+    BuiltInId::textureLod_Sampler2DShadow1_Float3_Float1,
+    BuiltInName::textureLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z2B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0H0C(
+    BuiltInId::textureSize_Sampler2D1_Int1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0P0C(
+    BuiltInId::textureSize_ISampler2D1_Int1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0U0C(
+    BuiltInId::textureSize_USampler2D1_Int1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0I0C(
+    BuiltInId::textureSize_Sampler3D1_Int1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0Q0C(
+    BuiltInId::textureSize_ISampler3D1_Int1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0V0C(
+    BuiltInId::textureSize_USampler3D1_Int1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0J0C(
+    BuiltInId::textureSize_SamplerCube1_Int1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0J0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0R0C(
+    BuiltInId::textureSize_ISamplerCube1_Int1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0R0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0W0C(
+    BuiltInId::textureSize_USamplerCube1_Int1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0W0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0K0C(
+    BuiltInId::textureSize_Sampler2DArray1_Int1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0K0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0S0C(
+    BuiltInId::textureSize_ISampler2DArray1_Int1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0S0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0X0C(
+    BuiltInId::textureSize_USampler2DArray1_Int1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0X0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0Z0C(
+    BuiltInId::textureSize_Sampler2DShadow1_Int1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0a0C(
+    BuiltInId::textureSize_SamplerCubeShadow1_Int1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0a0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0b0C(
+    BuiltInId::textureSize_Sampler2DArrayShadow1_Int1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0b0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0O(
+    BuiltInId::textureSize_Sampler2DMS1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0O1C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0T(
+    BuiltInId::textureSize_ISampler2DMS1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0T1C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0Y(
+    BuiltInId::textureSize_USampler2DMS1,
+    BuiltInName::textureSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Y1C0C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLod_0H2B0B(
+    BuiltInId::textureProjLod_Sampler2D1_Float3_Float1,
+    BuiltInName::textureProjLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H2B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLod_0P2B0B(
+    BuiltInId::textureProjLod_ISampler2D1_Float3_Float1,
+    BuiltInName::textureProjLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P2B0B1C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLod_0U2B0B(
+    BuiltInId::textureProjLod_USampler2D1_Float3_Float1,
+    BuiltInName::textureProjLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U2B0B1C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLod_0H3B0B(
+    BuiltInId::textureProjLod_Sampler2D1_Float4_Float1,
+    BuiltInName::textureProjLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H3B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLod_0P3B0B(
+    BuiltInId::textureProjLod_ISampler2D1_Float4_Float1,
+    BuiltInName::textureProjLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P3B0B1C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLod_0U3B0B(
+    BuiltInId::textureProjLod_USampler2D1_Float4_Float1,
+    BuiltInName::textureProjLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U3B0B1C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLod_0I3B0B(
+    BuiltInId::textureProjLod_Sampler3D1_Float4_Float1,
+    BuiltInName::textureProjLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I3B0B2C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLod_0Q3B0B(
+    BuiltInId::textureProjLod_ISampler3D1_Float4_Float1,
+    BuiltInName::textureProjLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q3B0B2C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLod_0V3B0B(
+    BuiltInId::textureProjLod_USampler3D1_Float4_Float1,
+    BuiltInName::textureProjLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V3B0B2C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLod_0Z3B0B(
+    BuiltInId::textureProjLod_Sampler2DShadow1_Float4_Float1,
+    BuiltInName::textureProjLod,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z3B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetch_0H1C0C(
+    BuiltInId::texelFetch_Sampler2D1_Int2_Int1,
+    BuiltInName::texelFetch,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H1C0C1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetch_0P1C0C(
+    BuiltInId::texelFetch_ISampler2D1_Int2_Int1,
+    BuiltInName::texelFetch,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P1C0C1C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetch_0U1C0C(
+    BuiltInId::texelFetch_USampler2D1_Int2_Int1,
+    BuiltInName::texelFetch,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U1C0C1C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetch_0I2C0C(
+    BuiltInId::texelFetch_Sampler3D1_Int3_Int1,
+    BuiltInName::texelFetch,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I2C0C2C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetch_0Q2C0C(
+    BuiltInId::texelFetch_ISampler3D1_Int3_Int1,
+    BuiltInName::texelFetch,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q2C0C2C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetch_0V2C0C(
+    BuiltInId::texelFetch_USampler3D1_Int3_Int1,
+    BuiltInName::texelFetch,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V2C0C2C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetch_0K2C0C(
+    BuiltInId::texelFetch_Sampler2DArray1_Int3_Int1,
+    BuiltInName::texelFetch,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0K2C0C1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetch_0S2C0C(
+    BuiltInId::texelFetch_ISampler2DArray1_Int3_Int1,
+    BuiltInName::texelFetch,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0S2C0C1C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetch_0X2C0C(
+    BuiltInId::texelFetch_USampler2DArray1_Int3_Int1,
+    BuiltInName::texelFetch,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0X2C0C1C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGrad_0H1B1B1B(
+    BuiltInId::textureGrad_Sampler2D1_Float2_Float2_Float2,
+    BuiltInName::textureGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H1B1B1B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGrad_0P1B1B1B(
+    BuiltInId::textureGrad_ISampler2D1_Float2_Float2_Float2,
+    BuiltInName::textureGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P1B1B1B1C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGrad_0U1B1B1B(
+    BuiltInId::textureGrad_USampler2D1_Float2_Float2_Float2,
+    BuiltInName::textureGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U1B1B1B1C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGrad_0I2B2B2B(
+    BuiltInId::textureGrad_Sampler3D1_Float3_Float3_Float3,
+    BuiltInName::textureGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I2B2B2B2C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGrad_0Q2B2B2B(
+    BuiltInId::textureGrad_ISampler3D1_Float3_Float3_Float3,
+    BuiltInName::textureGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q2B2B2B2C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGrad_0V2B2B2B(
+    BuiltInId::textureGrad_USampler3D1_Float3_Float3_Float3,
+    BuiltInName::textureGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V2B2B2B2C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGrad_0J2B2B2B(
+    BuiltInId::textureGrad_SamplerCube1_Float3_Float3_Float3,
+    BuiltInName::textureGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0J2B2B2B,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGrad_0R2B2B2B(
+    BuiltInId::textureGrad_ISamplerCube1_Float3_Float3_Float3,
+    BuiltInName::textureGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0R2B2B2B,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGrad_0W2B2B2B(
+    BuiltInId::textureGrad_USamplerCube1_Float3_Float3_Float3,
+    BuiltInName::textureGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0W2B2B2B,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGrad_0Z2B1B1B(
+    BuiltInId::textureGrad_Sampler2DShadow1_Float3_Float2_Float2,
+    BuiltInName::textureGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z2B1B1B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGrad_0a3B2B2B(
+    BuiltInId::textureGrad_SamplerCubeShadow1_Float4_Float3_Float3,
+    BuiltInName::textureGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0a3B2B2B,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGrad_0K2B1B1B(
+    BuiltInId::textureGrad_Sampler2DArray1_Float3_Float2_Float2,
+    BuiltInName::textureGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0K2B1B1B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGrad_0S2B1B1B(
+    BuiltInId::textureGrad_ISampler2DArray1_Float3_Float2_Float2,
+    BuiltInName::textureGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0S2B1B1B1C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGrad_0X2B1B1B(
+    BuiltInId::textureGrad_USampler2DArray1_Float3_Float2_Float2,
+    BuiltInName::textureGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0X2B1B1B1C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGrad_0b3B1B1B(
+    BuiltInId::textureGrad_Sampler2DArrayShadow1_Float4_Float2_Float2,
+    BuiltInName::textureGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0b3B1B1B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGrad_0H2B1B1B(
+    BuiltInId::textureProjGrad_Sampler2D1_Float3_Float2_Float2,
+    BuiltInName::textureProjGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H2B1B1B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGrad_0P2B1B1B(
+    BuiltInId::textureProjGrad_ISampler2D1_Float3_Float2_Float2,
+    BuiltInName::textureProjGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P2B1B1B1C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGrad_0U2B1B1B(
+    BuiltInId::textureProjGrad_USampler2D1_Float3_Float2_Float2,
+    BuiltInName::textureProjGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U2B1B1B1C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGrad_0H3B1B1B(
+    BuiltInId::textureProjGrad_Sampler2D1_Float4_Float2_Float2,
+    BuiltInName::textureProjGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H3B1B1B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGrad_0P3B1B1B(
+    BuiltInId::textureProjGrad_ISampler2D1_Float4_Float2_Float2,
+    BuiltInName::textureProjGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P3B1B1B1C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGrad_0U3B1B1B(
+    BuiltInId::textureProjGrad_USampler2D1_Float4_Float2_Float2,
+    BuiltInName::textureProjGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U3B1B1B1C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGrad_0I3B2B2B(
+    BuiltInId::textureProjGrad_Sampler3D1_Float4_Float3_Float3,
+    BuiltInName::textureProjGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I3B2B2B2C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGrad_0Q3B2B2B(
+    BuiltInId::textureProjGrad_ISampler3D1_Float4_Float3_Float3,
+    BuiltInName::textureProjGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q3B2B2B2C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGrad_0V3B2B2B(
+    BuiltInId::textureProjGrad_USampler3D1_Float4_Float3_Float3,
+    BuiltInName::textureProjGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V3B2B2B2C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGrad_0Z3B1B1B(
+    BuiltInId::textureProjGrad_Sampler2DShadow1_Float4_Float2_Float2,
+    BuiltInName::textureProjGrad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z3B1B1B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0H1B1C(
+    BuiltInId::textureOffset_Sampler2D1_Float2_Int2,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H1B1C0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0P1B1C(
+    BuiltInId::textureOffset_ISampler2D1_Float2_Int2,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P1B1C0B,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0U1B1C(
+    BuiltInId::textureOffset_USampler2D1_Float2_Int2,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U1B1C0C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0I2B2C(
+    BuiltInId::textureOffset_Sampler3D1_Float3_Int3,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I2B2C0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0Q2B2C(
+    BuiltInId::textureOffset_ISampler3D1_Float3_Int3,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q2B2C0B,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0V2B2C(
+    BuiltInId::textureOffset_USampler3D1_Float3_Int3,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V2B2C0B,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0Z2B1C(
+    BuiltInId::textureOffset_Sampler2DShadow1_Float3_Int2,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z2B1C0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0K2B1C(
+    BuiltInId::textureOffset_Sampler2DArray1_Float3_Int2,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0K2B1C0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0S2B1C(
+    BuiltInId::textureOffset_ISampler2DArray1_Float3_Int2,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0S2B1C0B,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0X2B1C(
+    BuiltInId::textureOffset_USampler2DArray1_Float3_Int2,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0X2B1C0C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0H2B1C(
+    BuiltInId::textureProjOffset_Sampler2D1_Float3_Int2,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H2B1C0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0P2B1C(
+    BuiltInId::textureProjOffset_ISampler2D1_Float3_Int2,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P2B1C0B,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0U2B1C(
+    BuiltInId::textureProjOffset_USampler2D1_Float3_Int2,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U2B1C0B,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0H3B1C(
+    BuiltInId::textureProjOffset_Sampler2D1_Float4_Int2,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H3B1C0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0P3B1C(
+    BuiltInId::textureProjOffset_ISampler2D1_Float4_Int2,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P3B1C0B,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0U3B1C(
+    BuiltInId::textureProjOffset_USampler2D1_Float4_Int2,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U3B1C0B,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0I3B2C(
+    BuiltInId::textureProjOffset_Sampler3D1_Float4_Int3,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I3B2C0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0Q3B2C(
+    BuiltInId::textureProjOffset_ISampler3D1_Float4_Int3,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q3B2C0B,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0V3B2C(
+    BuiltInId::textureProjOffset_USampler3D1_Float4_Int3,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V3B2C0B,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0Z3B1C(
+    BuiltInId::textureProjOffset_Sampler2DShadow1_Float4_Int2,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z3B1C0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLodOffset_0H1B0B1C(
+    BuiltInId::textureLodOffset_Sampler2D1_Float2_Float1_Int2,
+    BuiltInName::textureLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H1B0B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLodOffset_0P1B0B1C(
+    BuiltInId::textureLodOffset_ISampler2D1_Float2_Float1_Int2,
+    BuiltInName::textureLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P1B0B1C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLodOffset_0U1B0B1C(
+    BuiltInId::textureLodOffset_USampler2D1_Float2_Float1_Int2,
+    BuiltInName::textureLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U1B0B1C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLodOffset_0I2B0B2C(
+    BuiltInId::textureLodOffset_Sampler3D1_Float3_Float1_Int3,
+    BuiltInName::textureLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I2B0B2C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLodOffset_0Q2B0B2C(
+    BuiltInId::textureLodOffset_ISampler3D1_Float3_Float1_Int3,
+    BuiltInName::textureLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q2B0B2C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLodOffset_0V2B0B2C(
+    BuiltInId::textureLodOffset_USampler3D1_Float3_Float1_Int3,
+    BuiltInName::textureLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V2B0B2C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLodOffset_0Z2B0B1C(
+    BuiltInId::textureLodOffset_Sampler2DShadow1_Float3_Float1_Int2,
+    BuiltInName::textureLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z2B0B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLodOffset_0K2B0B1C(
+    BuiltInId::textureLodOffset_Sampler2DArray1_Float3_Float1_Int2,
+    BuiltInName::textureLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0K2B0B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLodOffset_0S2B0B1C(
+    BuiltInId::textureLodOffset_ISampler2DArray1_Float3_Float1_Int2,
+    BuiltInName::textureLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0S2B0B1C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureLodOffset_0X2B0B1C(
+    BuiltInId::textureLodOffset_USampler2DArray1_Float3_Float1_Int2,
+    BuiltInName::textureLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0X2B0B1C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLodOffset_0H2B0B1C(
+    BuiltInId::textureProjLodOffset_Sampler2D1_Float3_Float1_Int2,
+    BuiltInName::textureProjLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H2B0B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLodOffset_0P2B0B1C(
+    BuiltInId::textureProjLodOffset_ISampler2D1_Float3_Float1_Int2,
+    BuiltInName::textureProjLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P2B0B1C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLodOffset_0U2B0B1C(
+    BuiltInId::textureProjLodOffset_USampler2D1_Float3_Float1_Int2,
+    BuiltInName::textureProjLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U2B0B1C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLodOffset_0H3B0B1C(
+    BuiltInId::textureProjLodOffset_Sampler2D1_Float4_Float1_Int2,
+    BuiltInName::textureProjLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H3B0B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLodOffset_0P3B0B1C(
+    BuiltInId::textureProjLodOffset_ISampler2D1_Float4_Float1_Int2,
+    BuiltInName::textureProjLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P3B0B1C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLodOffset_0U3B0B1C(
+    BuiltInId::textureProjLodOffset_USampler2D1_Float4_Float1_Int2,
+    BuiltInName::textureProjLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U3B0B1C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLodOffset_0I3B0B2C(
+    BuiltInId::textureProjLodOffset_Sampler3D1_Float4_Float1_Int3,
+    BuiltInName::textureProjLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I3B0B2C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLodOffset_0Q3B0B2C(
+    BuiltInId::textureProjLodOffset_ISampler3D1_Float4_Float1_Int3,
+    BuiltInName::textureProjLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q3B0B2C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLodOffset_0V3B0B2C(
+    BuiltInId::textureProjLodOffset_USampler3D1_Float4_Float1_Int3,
+    BuiltInName::textureProjLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V3B0B2C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjLodOffset_0Z3B0B1C(
+    BuiltInId::textureProjLodOffset_Sampler2DShadow1_Float4_Float1_Int2,
+    BuiltInName::textureProjLodOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z3B0B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetchOffset_0H1C0C1C(
+    BuiltInId::texelFetchOffset_Sampler2D1_Int2_Int1_Int2,
+    BuiltInName::texelFetchOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H1C0C1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetchOffset_0P1C0C1C(
+    BuiltInId::texelFetchOffset_ISampler2D1_Int2_Int1_Int2,
+    BuiltInName::texelFetchOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P1C0C1C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetchOffset_0U1C0C1C(
+    BuiltInId::texelFetchOffset_USampler2D1_Int2_Int1_Int2,
+    BuiltInName::texelFetchOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U1C0C1C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetchOffset_0I2C0C2C(
+    BuiltInId::texelFetchOffset_Sampler3D1_Int3_Int1_Int3,
+    BuiltInName::texelFetchOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I2C0C2C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetchOffset_0Q2C0C2C(
+    BuiltInId::texelFetchOffset_ISampler3D1_Int3_Int1_Int3,
+    BuiltInName::texelFetchOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q2C0C2C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetchOffset_0V2C0C2C(
+    BuiltInId::texelFetchOffset_USampler3D1_Int3_Int1_Int3,
+    BuiltInName::texelFetchOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V2C0C2C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetchOffset_0K2C0C1C(
+    BuiltInId::texelFetchOffset_Sampler2DArray1_Int3_Int1_Int2,
+    BuiltInName::texelFetchOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0K2C0C1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetchOffset_0S2C0C1C(
+    BuiltInId::texelFetchOffset_ISampler2DArray1_Int3_Int1_Int2,
+    BuiltInName::texelFetchOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0S2C0C1C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetchOffset_0X2C0C1C(
+    BuiltInId::texelFetchOffset_USampler2DArray1_Int3_Int1_Int2,
+    BuiltInName::texelFetchOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0X2C0C1C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGradOffset_0H1B1B1B1C(
+    BuiltInId::textureGradOffset_Sampler2D1_Float2_Float2_Float2_Int2,
+    BuiltInName::textureGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H1B1B1B1C,
+    5,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGradOffset_0P1B1B1B1C(
+    BuiltInId::textureGradOffset_ISampler2D1_Float2_Float2_Float2_Int2,
+    BuiltInName::textureGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P1B1B1B1C,
+    5,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGradOffset_0U1B1B1B1C(
+    BuiltInId::textureGradOffset_USampler2D1_Float2_Float2_Float2_Int2,
+    BuiltInName::textureGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U1B1B1B1C,
+    5,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGradOffset_0I2B2B2B2C(
+    BuiltInId::textureGradOffset_Sampler3D1_Float3_Float3_Float3_Int3,
+    BuiltInName::textureGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I2B2B2B2C,
+    5,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGradOffset_0Q2B2B2B2C(
+    BuiltInId::textureGradOffset_ISampler3D1_Float3_Float3_Float3_Int3,
+    BuiltInName::textureGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q2B2B2B2C,
+    5,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGradOffset_0V2B2B2B2C(
+    BuiltInId::textureGradOffset_USampler3D1_Float3_Float3_Float3_Int3,
+    BuiltInName::textureGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V2B2B2B2C,
+    5,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGradOffset_0Z2B1B1B1C(
+    BuiltInId::textureGradOffset_Sampler2DShadow1_Float3_Float2_Float2_Int2,
+    BuiltInName::textureGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z2B1B1B1C,
+    5,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGradOffset_0K2B1B1B1C(
+    BuiltInId::textureGradOffset_Sampler2DArray1_Float3_Float2_Float2_Int2,
+    BuiltInName::textureGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0K2B1B1B1C,
+    5,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGradOffset_0S2B1B1B1C(
+    BuiltInId::textureGradOffset_ISampler2DArray1_Float3_Float2_Float2_Int2,
+    BuiltInName::textureGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0S2B1B1B1C,
+    5,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGradOffset_0X2B1B1B1C(
+    BuiltInId::textureGradOffset_USampler2DArray1_Float3_Float2_Float2_Int2,
+    BuiltInName::textureGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0X2B1B1B1C,
+    5,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGradOffset_0b3B1B1B1C(
+    BuiltInId::textureGradOffset_Sampler2DArrayShadow1_Float4_Float2_Float2_Int2,
+    BuiltInName::textureGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0b3B1B1B1C,
+    5,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGradOffset_0H2B1B1B1C(
+    BuiltInId::textureProjGradOffset_Sampler2D1_Float3_Float2_Float2_Int2,
+    BuiltInName::textureProjGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H2B1B1B1C,
+    5,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGradOffset_0P2B1B1B1C(
+    BuiltInId::textureProjGradOffset_ISampler2D1_Float3_Float2_Float2_Int2,
+    BuiltInName::textureProjGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P2B1B1B1C,
+    5,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGradOffset_0U2B1B1B1C(
+    BuiltInId::textureProjGradOffset_USampler2D1_Float3_Float2_Float2_Int2,
+    BuiltInName::textureProjGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U2B1B1B1C,
+    5,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGradOffset_0H3B1B1B1C(
+    BuiltInId::textureProjGradOffset_Sampler2D1_Float4_Float2_Float2_Int2,
+    BuiltInName::textureProjGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H3B1B1B1C,
+    5,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGradOffset_0P3B1B1B1C(
+    BuiltInId::textureProjGradOffset_ISampler2D1_Float4_Float2_Float2_Int2,
+    BuiltInName::textureProjGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P3B1B1B1C,
+    5,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGradOffset_0U3B1B1B1C(
+    BuiltInId::textureProjGradOffset_USampler2D1_Float4_Float2_Float2_Int2,
+    BuiltInName::textureProjGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U3B1B1B1C,
+    5,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGradOffset_0I3B2B2B2C(
+    BuiltInId::textureProjGradOffset_Sampler3D1_Float4_Float3_Float3_Int3,
+    BuiltInName::textureProjGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I3B2B2B2C,
+    5,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGradOffset_0Q3B2B2B2C(
+    BuiltInId::textureProjGradOffset_ISampler3D1_Float4_Float3_Float3_Int3,
+    BuiltInName::textureProjGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q3B2B2B2C,
+    5,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGradOffset_0V3B2B2B2C(
+    BuiltInId::textureProjGradOffset_USampler3D1_Float4_Float3_Float3_Int3,
+    BuiltInName::textureProjGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V3B2B2B2C,
+    5,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjGradOffset_0Z3B1B1B1C(
+    BuiltInId::textureProjGradOffset_Sampler2DShadow1_Float4_Float2_Float2_Int2,
+    BuiltInName::textureProjGradOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z3B1B1B1C,
+    5,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0H1B1C0B(
+    BuiltInId::textureOffset_Sampler2D1_Float2_Int2_Float1,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H1B1C0B,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0P1B1C0B(
+    BuiltInId::textureOffset_ISampler2D1_Float2_Int2_Float1,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P1B1C0B,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0U1B1C0B(
+    BuiltInId::textureOffset_USampler2D1_Float2_Int2_Float1,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U1B1C0B,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0I2B2C0B(
+    BuiltInId::textureOffset_Sampler3D1_Float3_Int3_Float1,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I2B2C0B,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0Q2B2C0B(
+    BuiltInId::textureOffset_ISampler3D1_Float3_Int3_Float1,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q2B2C0B,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0V2B2C0B(
+    BuiltInId::textureOffset_USampler3D1_Float3_Int3_Float1,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V2B2C0B,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0Z2B1C0B(
+    BuiltInId::textureOffset_Sampler2DShadow1_Float3_Int2_Float1,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z2B1C0B,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0K2B1C0B(
+    BuiltInId::textureOffset_Sampler2DArray1_Float3_Int2_Float1,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0K2B1C0B,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0S2B1C0B(
+    BuiltInId::textureOffset_ISampler2DArray1_Float3_Int2_Float1,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0S2B1C0B,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureOffset_0X2B1C0B(
+    BuiltInId::textureOffset_USampler2DArray1_Float3_Int2_Float1,
+    BuiltInName::textureOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0X2B1C0B,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0H2B1C0B(
+    BuiltInId::textureProjOffset_Sampler2D1_Float3_Int2_Float1,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H2B1C0B,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0P2B1C0B(
+    BuiltInId::textureProjOffset_ISampler2D1_Float3_Int2_Float1,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P2B1C0B,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0U2B1C0B(
+    BuiltInId::textureProjOffset_USampler2D1_Float3_Int2_Float1,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U2B1C0B,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0H3B1C0B(
+    BuiltInId::textureProjOffset_Sampler2D1_Float4_Int2_Float1,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H3B1C0B,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0P3B1C0B(
+    BuiltInId::textureProjOffset_ISampler2D1_Float4_Int2_Float1,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P3B1C0B,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0U3B1C0B(
+    BuiltInId::textureProjOffset_USampler2D1_Float4_Int2_Float1,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U3B1C0B,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0I3B2C0B(
+    BuiltInId::textureProjOffset_Sampler3D1_Float4_Int3_Float1,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I3B2C0B,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0Q3B2C0B(
+    BuiltInId::textureProjOffset_ISampler3D1_Float4_Int3_Float1,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q3B2C0B,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0V3B2C0B(
+    BuiltInId::textureProjOffset_USampler3D1_Float4_Int3_Float1,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V3B2C0B,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProjOffset_0Z3B1C0B(
+    BuiltInId::textureProjOffset_Sampler2DShadow1_Float4_Int2_Float1,
+    BuiltInName::textureProjOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z3B1C0B,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0L1B(
+    BuiltInId::texture_SamplerExternalOES1_Float2,
+    BuiltInName::texture,
+    TExtension::OES_EGL_image_external_essl3,
+    BuiltInParameters::p0L1B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0L2B(
+    BuiltInId::textureProj_SamplerExternalOES1_Float3,
+    BuiltInName::textureProj,
+    TExtension::OES_EGL_image_external_essl3,
+    BuiltInParameters::p0L2B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0L3B(
+    BuiltInId::textureProj_SamplerExternalOES1_Float4,
+    BuiltInName::textureProj,
+    TExtension::OES_EGL_image_external_essl3,
+    BuiltInParameters::p0L3B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0L0C(
+    BuiltInId::textureSize_SamplerExternalOES1_Int1,
+    BuiltInName::textureSize,
+    TExtension::OES_EGL_image_external_essl3,
+    BuiltInParameters::p0L0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetch_0L1C0C(
+    BuiltInId::texelFetch_SamplerExternalOES1_Int2_Int1,
+    BuiltInName::texelFetch,
+    TExtension::OES_EGL_image_external_essl3,
+    BuiltInParameters::p0L1C0C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0M1B(
+    BuiltInId::texture_SamplerExternal2DY2YEXT1_Float2,
+    BuiltInName::texture,
+    TExtension::EXT_YUV_target,
+    BuiltInParameters::p0M1B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0M2B(
+    BuiltInId::textureProj_SamplerExternal2DY2YEXT1_Float3,
+    BuiltInName::textureProj,
+    TExtension::EXT_YUV_target,
+    BuiltInParameters::p0M2B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0M3B(
+    BuiltInId::textureProj_SamplerExternal2DY2YEXT1_Float4,
+    BuiltInName::textureProj,
+    TExtension::EXT_YUV_target,
+    BuiltInParameters::p0M3B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_rgb_2_yuv_2B0G(
+    BuiltInId::rgb_2_yuv_Float3_YuvCscStandardEXT1,
+    BuiltInName::rgb_2_yuv,
+    TExtension::EXT_YUV_target,
+    BuiltInParameters::p2B0G,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_yuv_2_rgb_2B0G(
+    BuiltInId::yuv_2_rgb_Float3_YuvCscStandardEXT1,
+    BuiltInName::yuv_2_rgb,
+    TExtension::EXT_YUV_target,
+    BuiltInParameters::p2B0G,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureSize_0M0C(
+    BuiltInId::textureSize_SamplerExternal2DY2YEXT1_Int1,
+    BuiltInName::textureSize,
+    TExtension::EXT_YUV_target,
+    BuiltInParameters::p0M0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetch_0M1C0C(
+    BuiltInId::texelFetch_SamplerExternal2DY2YEXT1_Int2_Int1,
+    BuiltInName::texelFetch,
+    TExtension::EXT_YUV_target,
+    BuiltInParameters::p0M1C0C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0H1B0B(
+    BuiltInId::texture_Sampler2D1_Float2_Float1,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H1B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0P1B0B(
+    BuiltInId::texture_ISampler2D1_Float2_Float1,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P1B0B1C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0U1B0B(
+    BuiltInId::texture_USampler2D1_Float2_Float1,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U1B0B1C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0I2B0B(
+    BuiltInId::texture_Sampler3D1_Float3_Float1,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I2B0B2C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0Q2B0B(
+    BuiltInId::texture_ISampler3D1_Float3_Float1,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q2B0B2C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0V2B0B(
+    BuiltInId::texture_USampler3D1_Float3_Float1,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V2B0B2C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0J2B0B(
+    BuiltInId::texture_SamplerCube1_Float3_Float1,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0J2B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0R2B0B(
+    BuiltInId::texture_ISamplerCube1_Float3_Float1,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0R2B0B,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0W2B0B(
+    BuiltInId::texture_USamplerCube1_Float3_Float1,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0W2B0B,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0K2B0B(
+    BuiltInId::texture_Sampler2DArray1_Float3_Float1,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0K2B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0S2B0B(
+    BuiltInId::texture_ISampler2DArray1_Float3_Float1,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0S2B0B1C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0X2B0B(
+    BuiltInId::texture_USampler2DArray1_Float3_Float1,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0X2B0B1C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0H2B0B(
+    BuiltInId::textureProj_Sampler2D1_Float3_Float1,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H2B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0P2B0B(
+    BuiltInId::textureProj_ISampler2D1_Float3_Float1,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P2B0B1C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0U2B0B(
+    BuiltInId::textureProj_USampler2D1_Float3_Float1,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U2B0B1C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0H3B0B(
+    BuiltInId::textureProj_Sampler2D1_Float4_Float1,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H3B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0P3B0B(
+    BuiltInId::textureProj_ISampler2D1_Float4_Float1,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P3B0B1C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0U3B0B(
+    BuiltInId::textureProj_USampler2D1_Float4_Float1,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U3B0B1C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0I3B0B(
+    BuiltInId::textureProj_Sampler3D1_Float4_Float1,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0I3B0B2C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0Q3B0B(
+    BuiltInId::textureProj_ISampler3D1_Float4_Float1,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Q3B0B2C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0V3B0B(
+    BuiltInId::textureProj_USampler3D1_Float4_Float1,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0V3B0B2C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0Z2B0B(
+    BuiltInId::texture_Sampler2DShadow1_Float3_Float1,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z2B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0a3B0B(
+    BuiltInId::texture_SamplerCubeShadow1_Float4_Float1,
+    BuiltInName::texture,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0a3B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0Z3B0B(
+    BuiltInId::textureProj_Sampler2DShadow1_Float4_Float1,
+    BuiltInName::textureProj,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z3B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0L1B0B(
+    BuiltInId::texture_SamplerExternalOES1_Float2_Float1,
+    BuiltInName::texture,
+    TExtension::OES_EGL_image_external_essl3,
+    BuiltInParameters::p0L1B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0L2B0B(
+    BuiltInId::textureProj_SamplerExternalOES1_Float3_Float1,
+    BuiltInName::textureProj,
+    TExtension::OES_EGL_image_external_essl3,
+    BuiltInParameters::p0L2B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0L3B0B(
+    BuiltInId::textureProj_SamplerExternalOES1_Float4_Float1,
+    BuiltInName::textureProj,
+    TExtension::OES_EGL_image_external_essl3,
+    BuiltInParameters::p0L3B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texture_0M1B0B(
+    BuiltInId::texture_SamplerExternal2DY2YEXT1_Float2_Float1,
+    BuiltInName::texture,
+    TExtension::EXT_YUV_target,
+    BuiltInParameters::p0M1B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0M2B0B(
+    BuiltInId::textureProj_SamplerExternal2DY2YEXT1_Float3_Float1,
+    BuiltInName::textureProj,
+    TExtension::EXT_YUV_target,
+    BuiltInParameters::p0M2B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureProj_0M3B0B(
+    BuiltInId::textureProj_SamplerExternal2DY2YEXT1_Float4_Float1,
+    BuiltInName::textureProj,
+    TExtension::EXT_YUV_target,
+    BuiltInParameters::p0M3B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetch_0O1C0C(
+    BuiltInId::texelFetch_Sampler2DMS1_Int2_Int1,
+    BuiltInName::texelFetch,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0O1C0C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetch_0T1C0C(
+    BuiltInId::texelFetch_ISampler2DMS1_Int2_Int1,
+    BuiltInName::texelFetch,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0T1C0C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_texelFetch_0Y1C0C(
+    BuiltInId::texelFetch_USampler2DMS1_Int2_Int1,
+    BuiltInName::texelFetch,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Y1C0C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0H1B(
+    BuiltInId::textureGather_Sampler2D1_Float2,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H1B1B1B1C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0P1B(
+    BuiltInId::textureGather_ISampler2D1_Float2,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P1B0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0U1B(
+    BuiltInId::textureGather_USampler2D1_Float2,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U1B0B1C,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0H1B0C(
+    BuiltInId::textureGather_Sampler2D1_Float2_Int1,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H1B0C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0P1B0C(
+    BuiltInId::textureGather_ISampler2D1_Float2_Int1,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P1B0C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0U1B0C(
+    BuiltInId::textureGather_USampler2D1_Float2_Int1,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U1B0C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0K2B(
+    BuiltInId::textureGather_Sampler2DArray1_Float3,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0K2B0B1C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0S2B(
+    BuiltInId::textureGather_ISampler2DArray1_Float3,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0S2B0B1C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0X2B(
+    BuiltInId::textureGather_USampler2DArray1_Float3,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0X2B1C0C,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0K2B0C(
+    BuiltInId::textureGather_Sampler2DArray1_Float3_Int1,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0K2B0C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0S2B0C(
+    BuiltInId::textureGather_ISampler2DArray1_Float3_Int1,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0S2B0C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0X2B0C(
+    BuiltInId::textureGather_USampler2DArray1_Float3_Int1,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0X2B0C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0J2B(
+    BuiltInId::textureGather_SamplerCube1_Float3,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0J2B2B2B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0R2B(
+    BuiltInId::textureGather_ISamplerCube1_Float3,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0R2B2B2B,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0W2B(
+    BuiltInId::textureGather_USamplerCube1_Float3,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0W2B0B,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0J2B0C(
+    BuiltInId::textureGather_SamplerCube1_Float3_Int1,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0J2B0C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0R2B0C(
+    BuiltInId::textureGather_ISamplerCube1_Float3_Int1,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0R2B0C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0W2B0C(
+    BuiltInId::textureGather_USamplerCube1_Float3_Int1,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0W2B0C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0Z1B(
+    BuiltInId::textureGather_Sampler2DShadow1_Float2,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z1B0B1C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0Z1B0B(
+    BuiltInId::textureGather_Sampler2DShadow1_Float2_Float1,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z1B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0b2B(
+    BuiltInId::textureGather_Sampler2DArrayShadow1_Float3,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0b2B0B1C,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0b2B0B(
+    BuiltInId::textureGather_Sampler2DArrayShadow1_Float3_Float1,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0b2B0B1C,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0a2B(
+    BuiltInId::textureGather_SamplerCubeShadow1_Float3,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0a2B0B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGather_0a2B0B(
+    BuiltInId::textureGather_SamplerCubeShadow1_Float3_Float1,
+    BuiltInName::textureGather,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0a2B0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGatherOffset_0H1B1C(
+    BuiltInId::textureGatherOffset_Sampler2D1_Float2_Int2,
+    BuiltInName::textureGatherOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H1B1C0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGatherOffset_0P1B1C(
+    BuiltInId::textureGatherOffset_ISampler2D1_Float2_Int2,
+    BuiltInName::textureGatherOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P1B1C0B,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGatherOffset_0U1B1C(
+    BuiltInId::textureGatherOffset_USampler2D1_Float2_Int2,
+    BuiltInName::textureGatherOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U1B1C0C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGatherOffset_0H1B1C0C(
+    BuiltInId::textureGatherOffset_Sampler2D1_Float2_Int2_Int1,
+    BuiltInName::textureGatherOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0H1B1C0C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGatherOffset_0P1B1C0C(
+    BuiltInId::textureGatherOffset_ISampler2D1_Float2_Int2_Int1,
+    BuiltInName::textureGatherOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0P1B1C0C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGatherOffset_0U1B1C0C(
+    BuiltInId::textureGatherOffset_USampler2D1_Float2_Int2_Int1,
+    BuiltInName::textureGatherOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0U1B1C0C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGatherOffset_0K2B1C(
+    BuiltInId::textureGatherOffset_Sampler2DArray1_Float3_Int2,
+    BuiltInName::textureGatherOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0K2B1C0B,
+    3,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGatherOffset_0S2B1C(
+    BuiltInId::textureGatherOffset_ISampler2DArray1_Float3_Int2,
+    BuiltInName::textureGatherOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0S2B1C0B,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGatherOffset_0X2B1C(
+    BuiltInId::textureGatherOffset_USampler2DArray1_Float3_Int2,
+    BuiltInName::textureGatherOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0X2B1C0C,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGatherOffset_0K2B1C0C(
+    BuiltInId::textureGatherOffset_Sampler2DArray1_Float3_Int2_Int1,
+    BuiltInName::textureGatherOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0K2B1C0C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGatherOffset_0S2B1C0C(
+    BuiltInId::textureGatherOffset_ISampler2DArray1_Float3_Int2_Int1,
+    BuiltInName::textureGatherOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0S2B1C0C,
+    4,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGatherOffset_0X2B1C0C(
+    BuiltInId::textureGatherOffset_USampler2DArray1_Float3_Int2_Int1,
+    BuiltInName::textureGatherOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0X2B1C0C,
+    4,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGatherOffset_0Z1B0B1C(
+    BuiltInId::textureGatherOffset_Sampler2DShadow1_Float2_Float1_Int2,
+    BuiltInName::textureGatherOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0Z1B0B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_textureGatherOffset_0b2B0B1C(
+    BuiltInId::textureGatherOffset_Sampler2DArrayShadow1_Float3_Float1_Int2,
+    BuiltInName::textureGatherOffset,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0b2B0B1C,
+    4,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_dFdx_0B(
+    BuiltInId::dFdx_Float1,
+    BuiltInName::dFdx,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpDFdx,
+    false);
+constexpr const TFunction kFunction_dFdx_1B(
+    BuiltInId::dFdx_Float2,
+    BuiltInName::dFdx,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpDFdx,
+    false);
+constexpr const TFunction kFunction_dFdx_2B(
+    BuiltInId::dFdx_Float3,
+    BuiltInName::dFdx,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpDFdx,
+    false);
+constexpr const TFunction kFunction_dFdx_3B(
+    BuiltInId::dFdx_Float4,
+    BuiltInName::dFdx,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpDFdx,
+    false);
+constexpr const TFunction kFunction_dFdy_0B(
+    BuiltInId::dFdy_Float1,
+    BuiltInName::dFdy,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpDFdy,
+    false);
+constexpr const TFunction kFunction_dFdy_1B(
+    BuiltInId::dFdy_Float2,
+    BuiltInName::dFdy,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpDFdy,
+    false);
+constexpr const TFunction kFunction_dFdy_2B(
+    BuiltInId::dFdy_Float3,
+    BuiltInName::dFdy,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpDFdy,
+    false);
+constexpr const TFunction kFunction_dFdy_3B(
+    BuiltInId::dFdy_Float4,
+    BuiltInName::dFdy,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpDFdy,
+    false);
+constexpr const TFunction kFunction_fwidth_0B(
+    BuiltInId::fwidth_Float1,
+    BuiltInName::fwidth,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0B0C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpFwidth,
+    false);
+constexpr const TFunction kFunction_fwidth_1B(
+    BuiltInId::fwidth_Float2,
+    BuiltInName::fwidth,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p1B1B0B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpFwidth,
+    false);
+constexpr const TFunction kFunction_fwidth_2B(
+    BuiltInId::fwidth_Float3,
+    BuiltInName::fwidth,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p2B2C,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpFwidth,
+    false);
+constexpr const TFunction kFunction_fwidth_3B(
+    BuiltInId::fwidth_Float4,
+    BuiltInName::fwidth,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p3B1B,
+    1,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpFwidth,
+    false);
+constexpr const TFunction kFunction_atomicCounter_0F(
+    BuiltInId::atomicCounter_AtomicCounter1,
+    BuiltInName::atomicCounter,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0F,
+    1,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicCounterIncrement_0F(
+    BuiltInId::atomicCounterIncrement_AtomicCounter1,
+    BuiltInName::atomicCounterIncrement,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0F,
+    1,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicCounterDecrement_0F(
+    BuiltInId::atomicCounterDecrement_AtomicCounter1,
+    BuiltInName::atomicCounterDecrement,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0F,
+    1,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicAdd_0D0D(
+    BuiltInId::atomicAdd_UInt1_UInt1,
+    BuiltInName::atomicAdd,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p_io_0D0D0D,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicAdd_0C0C(
+    BuiltInId::atomicAdd_Int1_Int1,
+    BuiltInName::atomicAdd,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p_io_0C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicMin_0D0D(
+    BuiltInId::atomicMin_UInt1_UInt1,
+    BuiltInName::atomicMin,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p_io_0D0D0D,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicMin_0C0C(
+    BuiltInId::atomicMin_Int1_Int1,
+    BuiltInName::atomicMin,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p_io_0C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicMax_0D0D(
+    BuiltInId::atomicMax_UInt1_UInt1,
+    BuiltInName::atomicMax,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p_io_0D0D0D,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicMax_0C0C(
+    BuiltInId::atomicMax_Int1_Int1,
+    BuiltInName::atomicMax,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p_io_0C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicAnd_0D0D(
+    BuiltInId::atomicAnd_UInt1_UInt1,
+    BuiltInName::atomicAnd,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p_io_0D0D0D,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicAnd_0C0C(
+    BuiltInId::atomicAnd_Int1_Int1,
+    BuiltInName::atomicAnd,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p_io_0C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicOr_0D0D(
+    BuiltInId::atomicOr_UInt1_UInt1,
+    BuiltInName::atomicOr,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p_io_0D0D0D,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicOr_0C0C(
+    BuiltInId::atomicOr_Int1_Int1,
+    BuiltInName::atomicOr,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p_io_0C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicXor_0D0D(
+    BuiltInId::atomicXor_UInt1_UInt1,
+    BuiltInName::atomicXor,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p_io_0D0D0D,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicXor_0C0C(
+    BuiltInId::atomicXor_Int1_Int1,
+    BuiltInName::atomicXor,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p_io_0C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicExchange_0D0D(
+    BuiltInId::atomicExchange_UInt1_UInt1,
+    BuiltInName::atomicExchange,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p_io_0D0D0D,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicExchange_0C0C(
+    BuiltInId::atomicExchange_Int1_Int1,
+    BuiltInName::atomicExchange,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p_io_0C0C0C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicCompSwap_0D0D0D(
+    BuiltInId::atomicCompSwap_UInt1_UInt1_UInt1,
+    BuiltInName::atomicCompSwap,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p_io_0D0D0D,
+    3,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_atomicCompSwap_0C0C0C(
+    BuiltInId::atomicCompSwap_Int1_Int1_Int1,
+    BuiltInName::atomicCompSwap,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p_io_0C0C0C,
+    3,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageSize_0c(
+    BuiltInId::imageSize_Image2D1,
+    BuiltInName::imageSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0c1C3B,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageSize_0d(
+    BuiltInId::imageSize_IImage2D1,
+    BuiltInName::imageSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0d1C3C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageSize_0e(
+    BuiltInId::imageSize_UImage2D1,
+    BuiltInName::imageSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0e1C3D,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageSize_0f(
+    BuiltInId::imageSize_Image3D1,
+    BuiltInName::imageSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0f2C3B,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageSize_0g(
+    BuiltInId::imageSize_IImage3D1,
+    BuiltInName::imageSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0g2C3C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageSize_0h(
+    BuiltInId::imageSize_UImage3D1,
+    BuiltInName::imageSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0h2C3D,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageSize_0i(
+    BuiltInId::imageSize_Image2DArray1,
+    BuiltInName::imageSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0i2C3B,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageSize_0j(
+    BuiltInId::imageSize_IImage2DArray1,
+    BuiltInName::imageSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0j2C3C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageSize_0k(
+    BuiltInId::imageSize_UImage2DArray1,
+    BuiltInName::imageSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0k2C3D,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageSize_0l(
+    BuiltInId::imageSize_ImageCube1,
+    BuiltInName::imageSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0l2C3B,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageSize_0m(
+    BuiltInId::imageSize_IImageCube1,
+    BuiltInName::imageSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0m2C3C,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageSize_0n(
+    BuiltInId::imageSize_UImageCube1,
+    BuiltInName::imageSize,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0n2C3D,
+    1,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageLoad_0c1C(
+    BuiltInId::imageLoad_Image2D1_Int2,
+    BuiltInName::imageLoad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0c1C3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageLoad_0d1C(
+    BuiltInId::imageLoad_IImage2D1_Int2,
+    BuiltInName::imageLoad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0d1C3C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageLoad_0e1C(
+    BuiltInId::imageLoad_UImage2D1_Int2,
+    BuiltInName::imageLoad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0e1C3D,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageLoad_0f2C(
+    BuiltInId::imageLoad_Image3D1_Int3,
+    BuiltInName::imageLoad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0f2C3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageLoad_0g2C(
+    BuiltInId::imageLoad_IImage3D1_Int3,
+    BuiltInName::imageLoad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0g2C3C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageLoad_0h2C(
+    BuiltInId::imageLoad_UImage3D1_Int3,
+    BuiltInName::imageLoad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0h2C3D,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageLoad_0i2C(
+    BuiltInId::imageLoad_Image2DArray1_Int3,
+    BuiltInName::imageLoad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0i2C3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageLoad_0j2C(
+    BuiltInId::imageLoad_IImage2DArray1_Int3,
+    BuiltInName::imageLoad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0j2C3C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageLoad_0k2C(
+    BuiltInId::imageLoad_UImage2DArray1_Int3,
+    BuiltInName::imageLoad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0k2C3D,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageLoad_0l2C(
+    BuiltInId::imageLoad_ImageCube1_Int3,
+    BuiltInName::imageLoad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0l2C3B,
+    2,
+    StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageLoad_0m2C(
+    BuiltInId::imageLoad_IImageCube1_Int3,
+    BuiltInName::imageLoad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0m2C3C,
+    2,
+    StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageLoad_0n2C(
+    BuiltInId::imageLoad_UImageCube1_Int3,
+    BuiltInName::imageLoad,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0n2C3D,
+    2,
+    StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageStore_0c1C3B(
+    BuiltInId::imageStore_Image2D1_Int2_Float4,
+    BuiltInName::imageStore,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0c1C3B,
+    3,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageStore_0d1C3C(
+    BuiltInId::imageStore_IImage2D1_Int2_Int4,
+    BuiltInName::imageStore,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0d1C3C,
+    3,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageStore_0e1C3D(
+    BuiltInId::imageStore_UImage2D1_Int2_UInt4,
+    BuiltInName::imageStore,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0e1C3D,
+    3,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageStore_0f2C3B(
+    BuiltInId::imageStore_Image3D1_Int3_Float4,
+    BuiltInName::imageStore,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0f2C3B,
+    3,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageStore_0g2C3C(
+    BuiltInId::imageStore_IImage3D1_Int3_Int4,
+    BuiltInName::imageStore,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0g2C3C,
+    3,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageStore_0h2C3D(
+    BuiltInId::imageStore_UImage3D1_Int3_UInt4,
+    BuiltInName::imageStore,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0h2C3D,
+    3,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageStore_0i2C3B(
+    BuiltInId::imageStore_Image2DArray1_Int3_Float4,
+    BuiltInName::imageStore,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0i2C3B,
+    3,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageStore_0j2C3C(
+    BuiltInId::imageStore_IImage2DArray1_Int3_Int4,
+    BuiltInName::imageStore,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0j2C3C,
+    3,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageStore_0k2C3D(
+    BuiltInId::imageStore_UImage2DArray1_Int3_UInt4,
+    BuiltInName::imageStore,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0k2C3D,
+    3,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageStore_0l2C3B(
+    BuiltInId::imageStore_ImageCube1_Int3_Float4,
+    BuiltInName::imageStore,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0l2C3B,
+    3,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageStore_0m2C3C(
+    BuiltInId::imageStore_IImageCube1_Int3_Int4,
+    BuiltInName::imageStore,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0m2C3C,
+    3,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_imageStore_0n2C3D(
+    BuiltInId::imageStore_UImageCube1_Int3_UInt4,
+    BuiltInName::imageStore,
+    TExtension::UNDEFINED,
+    BuiltInParameters::p0n2C3D,
+    3,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpCallBuiltInFunction,
+    false);
+constexpr const TFunction kFunction_memoryBarrier_(
+    BuiltInId::memoryBarrier,
+    BuiltInName::memoryBarrier,
+    TExtension::UNDEFINED,
+    BuiltInParameters::empty,
+    0,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpMemoryBarrier,
+    false);
+constexpr const TFunction kFunction_memoryBarrierAtomicCounter_(
+    BuiltInId::memoryBarrierAtomicCounter,
+    BuiltInName::memoryBarrierAtomicCounter,
+    TExtension::UNDEFINED,
+    BuiltInParameters::empty,
+    0,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpMemoryBarrierAtomicCounter,
+    false);
+constexpr const TFunction kFunction_memoryBarrierBuffer_(
+    BuiltInId::memoryBarrierBuffer,
+    BuiltInName::memoryBarrierBuffer,
+    TExtension::UNDEFINED,
+    BuiltInParameters::empty,
+    0,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpMemoryBarrierBuffer,
+    false);
+constexpr const TFunction kFunction_memoryBarrierImage_(
+    BuiltInId::memoryBarrierImage,
+    BuiltInName::memoryBarrierImage,
+    TExtension::UNDEFINED,
+    BuiltInParameters::empty,
+    0,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpMemoryBarrierImage,
+    false);
+constexpr const TFunction kFunction_barrier_(
+    BuiltInId::barrier,
+    BuiltInName::barrier,
+    TExtension::UNDEFINED,
+    BuiltInParameters::empty,
+    0,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpBarrier,
+    false);
+constexpr const TFunction kFunction_memoryBarrierShared_(
+    BuiltInId::memoryBarrierShared,
+    BuiltInName::memoryBarrierShared,
+    TExtension::UNDEFINED,
+    BuiltInParameters::empty,
+    0,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpMemoryBarrierShared,
+    false);
+constexpr const TFunction kFunction_groupMemoryBarrier_(
+    BuiltInId::groupMemoryBarrier,
+    BuiltInName::groupMemoryBarrier,
+    TExtension::UNDEFINED,
+    BuiltInParameters::empty,
+    0,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpGroupMemoryBarrier,
+    false);
+constexpr const TFunction kFunction_EmitVertex_(
+    BuiltInId::EmitVertex,
+    BuiltInName::EmitVertex,
+    TExtension::EXT_geometry_shader,
+    BuiltInParameters::empty,
+    0,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpEmitVertex,
+    false);
+constexpr const TFunction kFunction_EndPrimitive_(
+    BuiltInId::EndPrimitive,
+    BuiltInName::EndPrimitive,
+    TExtension::EXT_geometry_shader,
+    BuiltInParameters::empty,
+    0,
+    StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+    EOpEndPrimitive,
+    false);
+
+}  // namespace BuiltInFunction
+
+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));
+    fields_gl_DepthRangeParameters->push_back(
+        new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1, 1), BuiltInName::far, zeroSourceLoc));
+    fields_gl_DepthRangeParameters->push_back(new TField(
+        new TType(EbtFloat, EbpHigh, EvqGlobal, 1, 1), BuiltInName::diff, zeroSourceLoc));
+    TStructure *gl_DepthRangeParameters =
+        new TStructure(BuiltInId::gl_DepthRangeParameters, BuiltInName::gl_DepthRangeParameters,
+                       TExtension::UNDEFINED, fields_gl_DepthRangeParameters);
+    mVar_gl_DepthRangeParameters = gl_DepthRangeParameters;
+    TType *type_gl_DepthRange    = new TType(gl_DepthRangeParameters);
+    type_gl_DepthRange->setQualifier(EvqUniform);
+    type_gl_DepthRange->realize();
+    mVar_gl_DepthRange =
+        new TVariable(BuiltInId::gl_DepthRange, BuiltInName::gl_DepthRange, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, type_gl_DepthRange);
+    mVar_gl_MaxVertexAttribs = new TVariable(
+        BuiltInId::gl_MaxVertexAttribs, BuiltInName::gl_MaxVertexAttribs, SymbolType::BuiltIn,
+        TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxVertexAttribs);
+        mVar_gl_MaxVertexAttribs->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxVertexUniformVectors =
+        new TVariable(BuiltInId::gl_MaxVertexUniformVectors,
+                      BuiltInName::gl_MaxVertexUniformVectors, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxVertexUniformVectors);
+        mVar_gl_MaxVertexUniformVectors->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxVertexTextureImageUnits =
+        new TVariable(BuiltInId::gl_MaxVertexTextureImageUnits,
+                      BuiltInName::gl_MaxVertexTextureImageUnits, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxVertexTextureImageUnits);
+        mVar_gl_MaxVertexTextureImageUnits->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxCombinedTextureImageUnits =
+        new TVariable(BuiltInId::gl_MaxCombinedTextureImageUnits,
+                      BuiltInName::gl_MaxCombinedTextureImageUnits, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxCombinedTextureImageUnits);
+        mVar_gl_MaxCombinedTextureImageUnits->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxTextureImageUnits =
+        new TVariable(BuiltInId::gl_MaxTextureImageUnits, BuiltInName::gl_MaxTextureImageUnits,
+                      SymbolType::BuiltIn, TExtension::UNDEFINED,
+                      StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxTextureImageUnits);
+        mVar_gl_MaxTextureImageUnits->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxFragmentUniformVectors =
+        new TVariable(BuiltInId::gl_MaxFragmentUniformVectors,
+                      BuiltInName::gl_MaxFragmentUniformVectors, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxFragmentUniformVectors);
+        mVar_gl_MaxFragmentUniformVectors->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxVaryingVectors = new TVariable(
+        BuiltInId::gl_MaxVaryingVectors, BuiltInName::gl_MaxVaryingVectors, SymbolType::BuiltIn,
+        TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxVaryingVectors);
+        mVar_gl_MaxVaryingVectors->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxDrawBuffers = new TVariable(
+        BuiltInId::gl_MaxDrawBuffers, BuiltInName::gl_MaxDrawBuffers, SymbolType::BuiltIn,
+        TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxDrawBuffers);
+        mVar_gl_MaxDrawBuffers->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxDualSourceDrawBuffersEXT = new TVariable(
+        BuiltInId::gl_MaxDualSourceDrawBuffersEXT, BuiltInName::gl_MaxDualSourceDrawBuffersEXT,
+        SymbolType::BuiltIn, TExtension::EXT_blend_func_extended,
+        StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxDualSourceDrawBuffers);
+        mVar_gl_MaxDualSourceDrawBuffersEXT->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxVertexOutputVectors =
+        new TVariable(BuiltInId::gl_MaxVertexOutputVectors, BuiltInName::gl_MaxVertexOutputVectors,
+                      SymbolType::BuiltIn, TExtension::UNDEFINED,
+                      StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxVertexOutputVectors);
+        mVar_gl_MaxVertexOutputVectors->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxFragmentInputVectors =
+        new TVariable(BuiltInId::gl_MaxFragmentInputVectors,
+                      BuiltInName::gl_MaxFragmentInputVectors, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxFragmentInputVectors);
+        mVar_gl_MaxFragmentInputVectors->shareConstPointer(unionArray);
+    }
+    mVar_gl_MinProgramTexelOffset =
+        new TVariable(BuiltInId::gl_MinProgramTexelOffset, BuiltInName::gl_MinProgramTexelOffset,
+                      SymbolType::BuiltIn, TExtension::UNDEFINED,
+                      StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MinProgramTexelOffset);
+        mVar_gl_MinProgramTexelOffset->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxProgramTexelOffset =
+        new TVariable(BuiltInId::gl_MaxProgramTexelOffset, BuiltInName::gl_MaxProgramTexelOffset,
+                      SymbolType::BuiltIn, TExtension::UNDEFINED,
+                      StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxProgramTexelOffset);
+        mVar_gl_MaxProgramTexelOffset->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxImageUnits = new TVariable(
+        BuiltInId::gl_MaxImageUnits, BuiltInName::gl_MaxImageUnits, SymbolType::BuiltIn,
+        TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxImageUnits);
+        mVar_gl_MaxImageUnits->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxVertexImageUniforms =
+        new TVariable(BuiltInId::gl_MaxVertexImageUniforms, BuiltInName::gl_MaxVertexImageUniforms,
+                      SymbolType::BuiltIn, TExtension::UNDEFINED,
+                      StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxVertexImageUniforms);
+        mVar_gl_MaxVertexImageUniforms->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxFragmentImageUniforms =
+        new TVariable(BuiltInId::gl_MaxFragmentImageUniforms,
+                      BuiltInName::gl_MaxFragmentImageUniforms, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxFragmentImageUniforms);
+        mVar_gl_MaxFragmentImageUniforms->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxComputeImageUniforms =
+        new TVariable(BuiltInId::gl_MaxComputeImageUniforms,
+                      BuiltInName::gl_MaxComputeImageUniforms, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxComputeImageUniforms);
+        mVar_gl_MaxComputeImageUniforms->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxCombinedImageUniforms =
+        new TVariable(BuiltInId::gl_MaxCombinedImageUniforms,
+                      BuiltInName::gl_MaxCombinedImageUniforms, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxCombinedImageUniforms);
+        mVar_gl_MaxCombinedImageUniforms->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxCombinedShaderOutputResources =
+        new TVariable(BuiltInId::gl_MaxCombinedShaderOutputResources,
+                      BuiltInName::gl_MaxCombinedShaderOutputResources, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxCombinedShaderOutputResources);
+        mVar_gl_MaxCombinedShaderOutputResources->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxComputeWorkGroupCount =
+        new TVariable(BuiltInId::gl_MaxComputeWorkGroupCount,
+                      BuiltInName::gl_MaxComputeWorkGroupCount, SymbolType::BuiltIn,
+                      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]);
+        }
+        mVar_gl_MaxComputeWorkGroupCount->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxComputeWorkGroupSize =
+        new TVariable(BuiltInId::gl_MaxComputeWorkGroupSize,
+                      BuiltInName::gl_MaxComputeWorkGroupSize, SymbolType::BuiltIn,
+                      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]);
+        }
+        mVar_gl_MaxComputeWorkGroupSize->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxComputeUniformComponents =
+        new TVariable(BuiltInId::gl_MaxComputeUniformComponents,
+                      BuiltInName::gl_MaxComputeUniformComponents, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxComputeUniformComponents);
+        mVar_gl_MaxComputeUniformComponents->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxComputeTextureImageUnits =
+        new TVariable(BuiltInId::gl_MaxComputeTextureImageUnits,
+                      BuiltInName::gl_MaxComputeTextureImageUnits, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxComputeTextureImageUnits);
+        mVar_gl_MaxComputeTextureImageUnits->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxComputeAtomicCounters =
+        new TVariable(BuiltInId::gl_MaxComputeAtomicCounters,
+                      BuiltInName::gl_MaxComputeAtomicCounters, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxComputeAtomicCounters);
+        mVar_gl_MaxComputeAtomicCounters->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxComputeAtomicCounterBuffers =
+        new TVariable(BuiltInId::gl_MaxComputeAtomicCounterBuffers,
+                      BuiltInName::gl_MaxComputeAtomicCounterBuffers, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxComputeAtomicCounterBuffers);
+        mVar_gl_MaxComputeAtomicCounterBuffers->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxVertexAtomicCounters =
+        new TVariable(BuiltInId::gl_MaxVertexAtomicCounters,
+                      BuiltInName::gl_MaxVertexAtomicCounters, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxVertexAtomicCounters);
+        mVar_gl_MaxVertexAtomicCounters->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxFragmentAtomicCounters =
+        new TVariable(BuiltInId::gl_MaxFragmentAtomicCounters,
+                      BuiltInName::gl_MaxFragmentAtomicCounters, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxFragmentAtomicCounters);
+        mVar_gl_MaxFragmentAtomicCounters->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxCombinedAtomicCounters =
+        new TVariable(BuiltInId::gl_MaxCombinedAtomicCounters,
+                      BuiltInName::gl_MaxCombinedAtomicCounters, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxCombinedAtomicCounters);
+        mVar_gl_MaxCombinedAtomicCounters->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxAtomicCounterBindings =
+        new TVariable(BuiltInId::gl_MaxAtomicCounterBindings,
+                      BuiltInName::gl_MaxAtomicCounterBindings, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxAtomicCounterBindings);
+        mVar_gl_MaxAtomicCounterBindings->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxVertexAtomicCounterBuffers =
+        new TVariable(BuiltInId::gl_MaxVertexAtomicCounterBuffers,
+                      BuiltInName::gl_MaxVertexAtomicCounterBuffers, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxVertexAtomicCounterBuffers);
+        mVar_gl_MaxVertexAtomicCounterBuffers->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxFragmentAtomicCounterBuffers =
+        new TVariable(BuiltInId::gl_MaxFragmentAtomicCounterBuffers,
+                      BuiltInName::gl_MaxFragmentAtomicCounterBuffers, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxFragmentAtomicCounterBuffers);
+        mVar_gl_MaxFragmentAtomicCounterBuffers->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxCombinedAtomicCounterBuffers =
+        new TVariable(BuiltInId::gl_MaxCombinedAtomicCounterBuffers,
+                      BuiltInName::gl_MaxCombinedAtomicCounterBuffers, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxCombinedAtomicCounterBuffers);
+        mVar_gl_MaxCombinedAtomicCounterBuffers->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxAtomicCounterBufferSize =
+        new TVariable(BuiltInId::gl_MaxAtomicCounterBufferSize,
+                      BuiltInName::gl_MaxAtomicCounterBufferSize, SymbolType::BuiltIn,
+                      TExtension::UNDEFINED, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxAtomicCounterBufferSize);
+        mVar_gl_MaxAtomicCounterBufferSize->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxGeometryInputComponents = new TVariable(
+        BuiltInId::gl_MaxGeometryInputComponents, BuiltInName::gl_MaxGeometryInputComponents,
+        SymbolType::BuiltIn, TExtension::EXT_geometry_shader,
+        StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxGeometryInputComponents);
+        mVar_gl_MaxGeometryInputComponents->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxGeometryOutputComponents = new TVariable(
+        BuiltInId::gl_MaxGeometryOutputComponents, BuiltInName::gl_MaxGeometryOutputComponents,
+        SymbolType::BuiltIn, TExtension::EXT_geometry_shader,
+        StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxGeometryOutputComponents);
+        mVar_gl_MaxGeometryOutputComponents->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxGeometryImageUniforms = new TVariable(
+        BuiltInId::gl_MaxGeometryImageUniforms, BuiltInName::gl_MaxGeometryImageUniforms,
+        SymbolType::BuiltIn, TExtension::EXT_geometry_shader,
+        StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxGeometryImageUniforms);
+        mVar_gl_MaxGeometryImageUniforms->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxGeometryTextureImageUnits = new TVariable(
+        BuiltInId::gl_MaxGeometryTextureImageUnits, BuiltInName::gl_MaxGeometryTextureImageUnits,
+        SymbolType::BuiltIn, TExtension::EXT_geometry_shader,
+        StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxGeometryTextureImageUnits);
+        mVar_gl_MaxGeometryTextureImageUnits->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxGeometryOutputVertices = new TVariable(
+        BuiltInId::gl_MaxGeometryOutputVertices, BuiltInName::gl_MaxGeometryOutputVertices,
+        SymbolType::BuiltIn, TExtension::EXT_geometry_shader,
+        StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxGeometryOutputVertices);
+        mVar_gl_MaxGeometryOutputVertices->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxGeometryTotalOutputComponents = new TVariable(
+        BuiltInId::gl_MaxGeometryTotalOutputComponents,
+        BuiltInName::gl_MaxGeometryTotalOutputComponents, SymbolType::BuiltIn,
+        TExtension::EXT_geometry_shader, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxGeometryTotalOutputComponents);
+        mVar_gl_MaxGeometryTotalOutputComponents->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxGeometryUniformComponents = new TVariable(
+        BuiltInId::gl_MaxGeometryUniformComponents, BuiltInName::gl_MaxGeometryUniformComponents,
+        SymbolType::BuiltIn, TExtension::EXT_geometry_shader,
+        StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxGeometryUniformComponents);
+        mVar_gl_MaxGeometryUniformComponents->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxGeometryAtomicCounters = new TVariable(
+        BuiltInId::gl_MaxGeometryAtomicCounters, BuiltInName::gl_MaxGeometryAtomicCounters,
+        SymbolType::BuiltIn, TExtension::EXT_geometry_shader,
+        StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxGeometryAtomicCounters);
+        mVar_gl_MaxGeometryAtomicCounters->shareConstPointer(unionArray);
+    }
+    mVar_gl_MaxGeometryAtomicCounterBuffers = new TVariable(
+        BuiltInId::gl_MaxGeometryAtomicCounterBuffers,
+        BuiltInName::gl_MaxGeometryAtomicCounterBuffers, SymbolType::BuiltIn,
+        TExtension::EXT_geometry_shader, StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+    {
+        TConstantUnion *unionArray = new TConstantUnion[1];
+        unionArray[0].setIConst(resources.MaxGeometryAtomicCounterBuffers);
+        mVar_gl_MaxGeometryAtomicCounterBuffers->shareConstPointer(unionArray);
+    }
+    if (shaderType == GL_FRAGMENT_SHADER)
+    {
+        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();
+        mVar_gl_FragData =
+            new TVariable(BuiltInId::gl_FragData, BuiltInName::gl_FragData, SymbolType::BuiltIn,
+                          TExtension::UNDEFINED, type_gl_FragData);
+    }
+    if ((shaderType == GL_FRAGMENT_SHADER) && (mResources.EXT_blend_func_extended))
+    {
+        TType *type_gl_SecondaryFragDataEXT =
+            new TType(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1);
+        type_gl_SecondaryFragDataEXT->makeArray(resources.MaxDualSourceDrawBuffers);
+        type_gl_SecondaryFragDataEXT->realize();
+        mVar_gl_SecondaryFragDataEXT = new TVariable(
+            BuiltInId::gl_SecondaryFragDataEXT, BuiltInName::gl_SecondaryFragDataEXT,
+            SymbolType::BuiltIn, TExtension::EXT_blend_func_extended, type_gl_SecondaryFragDataEXT);
+    }
+    if ((shaderType == GL_FRAGMENT_SHADER) && (mResources.EXT_frag_depth))
+    {
+        TType *type_gl_FragDepthEXT = new TType(
+            EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepthEXT, 1);
+        type_gl_FragDepthEXT->realize();
+        mVar_gl_FragDepthEXT =
+            new TVariable(BuiltInId::gl_FragDepthEXT, BuiltInName::gl_FragDepthEXT,
+                          SymbolType::BuiltIn, 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();
+    mVar_gl_LastFragData =
+        new TVariable(BuiltInId::gl_LastFragData, BuiltInName::gl_LastFragData, SymbolType::BuiltIn,
+                      TExtension::EXT_shader_framebuffer_fetch, type_gl_LastFragData);
+    TType *type_gl_LastFragDataNV = new TType(EbtFloat, EbpMedium, EvqLastFragData, 4, 1);
+    type_gl_LastFragDataNV->makeArray(resources.MaxDrawBuffers);
+    type_gl_LastFragDataNV->realize();
+    mVar_gl_LastFragDataNV = new TVariable(
+        BuiltInId::gl_LastFragDataNV, BuiltInName::gl_LastFragData, SymbolType::BuiltIn,
+        TExtension::NV_shader_framebuffer_fetch, type_gl_LastFragDataNV);
+    TFieldList *fields_gl_PerVertex = new TFieldList();
+    fields_gl_PerVertex->push_back(new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1),
+                                              BuiltInName::gl_Position, zeroSourceLoc));
+    TInterfaceBlock *gl_PerVertex =
+        new TInterfaceBlock(BuiltInId::gl_PerVertex, BuiltInName::gl_PerVertex,
+                            TExtension::EXT_geometry_shader, fields_gl_PerVertex);
+    mVar_gl_PerVertex = gl_PerVertex;
+    if (shaderType == GL_GEOMETRY_SHADER_EXT)
+    {
+        TType *type_gl_in = new TType(gl_PerVertex, EvqPerVertexIn, TLayoutQualifier::Create());
+        type_gl_in->makeArray(0u);
+        type_gl_in->realize();
+        mVar_gl_in = new TVariable(BuiltInId::gl_in, BuiltInName::gl_in, SymbolType::BuiltIn,
+                                   TExtension::EXT_geometry_shader, type_gl_in);
+    }
+    TFieldList *fields_gl_PerVertexOutBlock = new TFieldList();
+    fields_gl_PerVertexOutBlock->push_back(new TField(
+        new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position, zeroSourceLoc));
+    TInterfaceBlock *gl_PerVertexOutBlock =
+        new TInterfaceBlock(BuiltInId::gl_PerVertexOutBlock, BuiltInName::gl_PerVertex,
+                            TExtension::EXT_geometry_shader, fields_gl_PerVertexOutBlock);
+    TType *type_gl_PositionGS = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
+    type_gl_PositionGS->setInterfaceBlock(gl_PerVertexOutBlock);
+    type_gl_PositionGS->realize();
+    mVar_gl_PositionGS =
+        new TVariable(BuiltInId::gl_PositionGS, BuiltInName::gl_Position, SymbolType::BuiltIn,
+                      TExtension::EXT_geometry_shader, type_gl_PositionGS);
+}
+
+const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name, int shaderVersion) const
+{
+    if (name.length() > 35)
+    {
+        return nullptr;
+    }
+    uint32_t nameHash = name.mangledNameHash();
+    if ((nameHash >> 31) != 0)
+    {
+        // The name contains [ or {.
+        return nullptr;
+    }
+    if (shaderVersion >= 310)
+    {
+        switch (nameHash)
+        {
+            case 0x0a50832eu:
+            {
+                if (name.beginsWith(BuiltInName::ldexp))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_ldexp_1B1C;
+                }
+                break;
+            }
+            case 0x0a50a6eeu:
+            {
+                if (name.beginsWith(BuiltInName::frexp))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_frexp_2B2C;
+                }
+                break;
+            }
+            case 0x0a52bed1u:
+            {
+                if (name.beginsWith(BuiltInName::ldexp))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_ldexp_0B0C;
+                }
+                break;
+            }
+            case 0x0a53e9c4u:
+            {
+                if (name == BuiltInName::frexp_3B3C)
+                {
+                    return &BuiltInFunction::kFunction_frexp_3B3C;
+                }
+                break;
+            }
+            case 0x0a54aa52u:
+            {
+                if (name.beginsWith(BuiltInName::ldexp))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_ldexp_2B2C;
+                }
+                break;
+            }
+            case 0x0a55008fu:
+            {
+                if (name.beginsWith(BuiltInName::frexp))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_frexp_1B1C;
+                }
+                break;
+            }
+            case 0x0a5799e7u:
+            {
+                if (name.beginsWith(BuiltInName::frexp))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_frexp_0B0C;
+                }
+                break;
+            }
+            case 0x0a57c201u:
+            {
+                if (name.beginsWith(BuiltInName::ldexp))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_ldexp_3B3C;
+                }
+                break;
+            }
+            case 0x0e500330u:
+            {
+                if (name.beginsWith(BuiltInName::findMSB))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_findMSB_3C;
+                }
+                break;
+            }
+            case 0x0e503089u:
+            {
+                if (name.beginsWith(BuiltInName::findMSB))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_findMSB_3D;
+                }
+                break;
+            }
+            case 0x0e508070u:
+            {
+                if (name.beginsWith(BuiltInName::findMSB))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_findMSB_0C;
+                }
+                break;
+            }
+            case 0x0e508a05u:
+            {
+                if (name.beginsWith(BuiltInName::findMSB))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_findMSB_0D;
+                }
+                break;
+            }
+            case 0x0e51917du:
+            {
+                if (name.beginsWith(BuiltInName::findMSB))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_findMSB_1C;
+                }
+                break;
+            }
+            case 0x0e51dc78u:
+            {
+                if (name.beginsWith(BuiltInName::findMSB))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_findMSB_1D;
+                }
+                break;
+            }
+            case 0x0e54832eu:
+            {
+                if (name.beginsWith(BuiltInName::findLSB))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_findLSB_2C;
+                }
+                break;
+            }
+            case 0x0e54b667u:
+            {
+                if (name.beginsWith(BuiltInName::findLSB))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_findLSB_2D;
+                }
+                break;
+            }
+            case 0x0e550f72u:
+            {
+                if (name.beginsWith(BuiltInName::findLSB))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_findLSB_1D;
+                }
+                break;
+            }
+            case 0x0e5514e7u:
+            {
+                if (name.beginsWith(BuiltInName::findLSB))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_findLSB_1C;
+                }
+                break;
+            }
+            case 0x0e5607c2u:
+            {
+                if (name.beginsWith(BuiltInName::findLSB))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_findLSB_0C;
+                }
+                break;
+            }
+            case 0x0e5650c7u:
+            {
+                if (name.beginsWith(BuiltInName::findLSB))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_findLSB_0D;
+                }
+                break;
+            }
+            case 0x0e56a99cu:
+            {
+                if (name.beginsWith(BuiltInName::findMSB))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_findMSB_2D;
+                }
+                break;
+            }
+            case 0x0e56cd55u:
+            {
+                if (name.beginsWith(BuiltInName::findMSB))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_findMSB_2C;
+                }
+                break;
+            }
+            case 0x0e573680u:
+            {
+                if (name.beginsWith(BuiltInName::findLSB))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_findLSB_3D;
+                }
+                break;
+            }
+            case 0x0e574a59u:
+            {
+                if (name.beginsWith(BuiltInName::findLSB))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_findLSB_3C;
+                }
+                break;
+            }
+            case 0x10581cccu:
+            {
+                if (name.beginsWith(BuiltInName::bitCount))
+                {
+                    ASSERT(name.length() == 11);
+                    return &BuiltInFunction::kFunction_bitCount_2D;
+                }
+                break;
+            }
+            case 0x10584c2du:
+            {
+                if (name.beginsWith(BuiltInName::bitCount))
+                {
+                    ASSERT(name.length() == 11);
+                    return &BuiltInFunction::kFunction_bitCount_2C;
+                }
+                break;
+            }
+            case 0x105896f1u:
+            {
+                if (name.beginsWith(BuiltInName::bitCount))
+                {
+                    ASSERT(name.length() == 11);
+                    return &BuiltInFunction::kFunction_bitCount_1D;
+                }
+                break;
+            }
+            case 0x1058cbf7u:
+            {
+                if (name.beginsWith(BuiltInName::bitCount))
+                {
+                    ASSERT(name.length() == 11);
+                    return &BuiltInFunction::kFunction_bitCount_1C;
+                }
+                break;
+            }
+            case 0x1059a37cu:
+            {
+                if (name.beginsWith(BuiltInName::bitCount))
+                {
+                    ASSERT(name.length() == 11);
+                    return &BuiltInFunction::kFunction_bitCount_0D;
+                }
+                break;
+            }
+            case 0x1059dae9u:
+            {
+                if (name.beginsWith(BuiltInName::bitCount))
+                {
+                    ASSERT(name.length() == 11);
+                    return &BuiltInFunction::kFunction_bitCount_0C;
+                }
+                break;
+            }
+            case 0x105b1832u:
+            {
+                if (name.beginsWith(BuiltInName::bitCount))
+                {
+                    ASSERT(name.length() == 11);
+                    return &BuiltInFunction::kFunction_bitCount_3C;
+                }
+                break;
+            }
+            case 0x105b2810u:
+            {
+                if (name.beginsWith(BuiltInName::bitCount))
+                {
+                    ASSERT(name.length() == 11);
+                    return &BuiltInFunction::kFunction_bitCount_3D;
+                }
+                break;
+            }
+            case 0x106a2daeu:
+            {
+                if (name.beginsWith(BuiltInName::atomicOr))
+                {
+                    ASSERT(name.length() == 13);
+                    return &BuiltInFunction::kFunction_atomicOr_0D0D;
+                }
+                break;
+            }
+            case 0x106bd5b6u:
+            {
+                if (name.beginsWith(BuiltInName::atomicOr))
+                {
+                    ASSERT(name.length() == 13);
+                    return &BuiltInFunction::kFunction_atomicOr_0C0C;
+                }
+                break;
+            }
+            case 0x12659f72u:
+            {
+                if (name.beginsWith(BuiltInName::imageSize))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_imageSize_0c;
+                }
+                break;
+            }
+            case 0x1265b53eu:
+            {
+                if (name.beginsWith(BuiltInName::imageSize))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_imageSize_0g;
+                }
+                break;
+            }
+            case 0x1265c077u:
+            {
+                if (name.beginsWith(BuiltInName::imageSize))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_imageSize_0d;
+                }
+                break;
+            }
+            case 0x1265c6e0u:
+            {
+                if (name.beginsWith(BuiltInName::imageSize))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_imageSize_0e;
+                }
+                break;
+            }
+            case 0x1265cbcau:
+            {
+                if (name.beginsWith(BuiltInName::imageSize))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_imageSize_0k;
+                }
+                break;
+            }
+            case 0x1265cc8du:
+            {
+                if (name.beginsWith(BuiltInName::imageSize))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_imageSize_0f;
+                }
+                break;
+            }
+            case 0x1265e603u:
+            {
+                if (name.beginsWith(BuiltInName::imageSize))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_imageSize_0h;
+                }
+                break;
+            }
+            case 0x1265f559u:
+            {
+                if (name.beginsWith(BuiltInName::imageSize))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_imageSize_0j;
+                }
+                break;
+            }
+            case 0x1265fcacu:
+            {
+                if (name.beginsWith(BuiltInName::imageSize))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_imageSize_0i;
+                }
+                break;
+            }
+            case 0x12660ccfu:
+            {
+                if (name.beginsWith(BuiltInName::imageSize))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_imageSize_0l;
+                }
+                break;
+            }
+            case 0x12661578u:
+            {
+                if (name.beginsWith(BuiltInName::imageSize))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_imageSize_0m;
+                }
+                break;
+            }
+            case 0x12661be5u:
+            {
+                if (name.beginsWith(BuiltInName::imageSize))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_imageSize_0n;
+                }
+                break;
+            }
+            case 0x12701a06u:
+            {
+                if (name.beginsWith(BuiltInName::imageLoad))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_imageLoad_0g2C;
+                }
+                break;
+            }
+            case 0x1270829bu:
+            {
+                if (name.beginsWith(BuiltInName::imageLoad))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_imageLoad_0h2C;
+                }
+                break;
+            }
+            case 0x1270b3f8u:
+            {
+                if (name.beginsWith(BuiltInName::atomicAdd))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_atomicAdd_0C0C;
+                }
+                break;
+            }
+            case 0x1270b766u:
+            {
+                if (name.beginsWith(BuiltInName::atomicXor))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_atomicXor_0C0C;
+                }
+                break;
+            }
+            case 0x12712664u:
+            {
+                if (name.beginsWith(BuiltInName::imageLoad))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_imageLoad_0n2C;
+                }
+                break;
+            }
+            case 0x12715f47u:
+            {
+                if (name.beginsWith(BuiltInName::imageLoad))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_imageLoad_0j2C;
+                }
+                break;
+            }
+            case 0x12717c89u:
+            {
+                if (name.beginsWith(BuiltInName::atomicMin))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_atomicMin_0C0C;
+                }
+                break;
+            }
+            case 0x127258f0u:
+            {
+                if (name.beginsWith(BuiltInName::atomicAdd))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_atomicAdd_0D0D;
+                }
+                break;
+            }
+            case 0x12731984u:
+            {
+                if (name.beginsWith(BuiltInName::imageLoad))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_imageLoad_0m2C;
+                }
+                break;
+            }
+            case 0x12737e4du:
+            {
+                if (name.beginsWith(BuiltInName::imageLoad))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_imageLoad_0c1C;
+                }
+                break;
+            }
+            case 0x1273b8c5u:
+            {
+                if (name.beginsWith(BuiltInName::imageLoad))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_imageLoad_0d1C;
+                }
+                break;
+            }
+            case 0x1273d1adu:
+            {
+                if (name.beginsWith(BuiltInName::atomicMax))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_atomicMax_0D0D;
+                }
+                break;
+            }
+            case 0x1273e62au:
+            {
+                if (name.beginsWith(BuiltInName::atomicMin))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_atomicMin_0D0D;
+                }
+                break;
+            }
+            case 0x127474cau:
+            {
+                if (name.beginsWith(BuiltInName::imageLoad))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_imageLoad_0k2C;
+                }
+                break;
+            }
+            case 0x127478d9u:
+            {
+                if (name.beginsWith(BuiltInName::atomicAnd))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_atomicAnd_0C0C;
+                }
+                break;
+            }
+            case 0x1274d104u:
+            {
+                if (name.beginsWith(BuiltInName::imageLoad))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_imageLoad_0f2C;
+                }
+                break;
+            }
+            case 0x127539b2u:
+            {
+                if (name.beginsWith(BuiltInName::imageLoad))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_imageLoad_0i2C;
+                }
+                break;
+            }
+            case 0x12754b32u:
+            {
+                if (name.beginsWith(BuiltInName::imageLoad))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_imageLoad_0e1C;
+                }
+                break;
+            }
+            case 0x127648cau:
+            {
+                if (name.beginsWith(BuiltInName::atomicAnd))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_atomicAnd_0D0D;
+                }
+                break;
+            }
+            case 0x1276656cu:
+            {
+                if (name.beginsWith(BuiltInName::imageLoad))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_imageLoad_0l2C;
+                }
+                break;
+            }
+            case 0x12771119u:
+            {
+                if (name.beginsWith(BuiltInName::atomicXor))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_atomicXor_0D0D;
+                }
+                break;
+            }
+            case 0x1277882au:
+            {
+                if (name.beginsWith(BuiltInName::atomicMax))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_atomicMax_0C0C;
+                }
+                break;
+            }
+            case 0x1283ba95u:
+            {
+                if (name.beginsWith(BuiltInName::uaddCarry))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_uaddCarry_0D0D0D;
+                }
+                break;
+            }
+            case 0x12840dfbu:
+            {
+                if (name == BuiltInName::uaddCarry_2D2D2D)
+                {
+                    return &BuiltInFunction::kFunction_uaddCarry_2D2D2D;
+                }
+                break;
+            }
+            case 0x12842566u:
+            {
+                if (name == BuiltInName::uaddCarry_3D3D3D)
+                {
+                    return &BuiltInFunction::kFunction_uaddCarry_3D3D3D;
+                }
+                break;
+            }
+            case 0x12843bc0u:
+            {
+                if (name.beginsWith(BuiltInName::uaddCarry))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_uaddCarry_1D1D1D;
+                }
+                break;
+            }
+            case 0x1488078cu:
+            {
+                if (name.beginsWith(BuiltInName::imageStore))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_imageStore_0k2C3D;
+                }
+                break;
+            }
+            case 0x1488ffa7u:
+            {
+                if (name == BuiltInName::usubBorrow_3D3D3D)
+                {
+                    return &BuiltInFunction::kFunction_usubBorrow_3D3D3D;
+                }
+                break;
+            }
+            case 0x14896692u:
+            {
+                if (name.beginsWith(BuiltInName::usubBorrow))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_usubBorrow_2D2D2D;
+                }
+                break;
+            }
+            case 0x14896e41u:
+            {
+                if (name == BuiltInName::texelFetch_0O1C0C)
+                {
+                    return &BuiltInFunction::kFunction_texelFetch_0O1C0C;
+                }
+                break;
+            }
+            case 0x148ab5f1u:
+            {
+                if (name == BuiltInName::usubBorrow_1D1D1D)
+                {
+                    return &BuiltInFunction::kFunction_usubBorrow_1D1D1D;
+                }
+                break;
+            }
+            case 0x148aca44u:
+            {
+                if (name == BuiltInName::imageStore_0d1C3C)
+                {
+                    return &BuiltInFunction::kFunction_imageStore_0d1C3C;
+                }
+                break;
+            }
+            case 0x148c1ac9u:
+            {
+                if (name == BuiltInName::texelFetch_0T1C0C)
+                {
+                    return &BuiltInFunction::kFunction_texelFetch_0T1C0C;
+                }
+                break;
+            }
+            case 0x148c5f8bu:
+            {
+                if (name.beginsWith(BuiltInName::imageStore))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_imageStore_0f2C3B;
+                }
+                break;
+            }
+            case 0x148d6aebu:
+            {
+                if (name == BuiltInName::imageStore_0c1C3B)
+                {
+                    return &BuiltInFunction::kFunction_imageStore_0c1C3B;
+                }
+                break;
+            }
+            case 0x148d8868u:
+            {
+                if (name.beginsWith(BuiltInName::imageStore))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_imageStore_0g2C3C;
+                }
+                break;
+            }
+            case 0x148dcfd5u:
+            {
+                if (name == BuiltInName::imageStore_0l2C3B)
+                {
+                    return &BuiltInFunction::kFunction_imageStore_0l2C3B;
+                }
+                break;
+            }
+            case 0x148dd2bdu:
+            {
+                if (name.beginsWith(BuiltInName::texelFetch))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_texelFetch_0Y1C0C;
+                }
+                break;
+            }
+            case 0x148e37b8u:
+            {
+                if (name.beginsWith(BuiltInName::imageStore))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_imageStore_0m2C3C;
+                }
+                break;
+            }
+            case 0x148e668au:
+            {
+                if (name.beginsWith(BuiltInName::imageStore))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_imageStore_0j2C3C;
+                }
+                break;
+            }
+            case 0x148ed534u:
+            {
+                if (name == BuiltInName::imageStore_0n2C3D)
+                {
+                    return &BuiltInFunction::kFunction_imageStore_0n2C3D;
+                }
+                break;
+            }
+            case 0x148f334cu:
+            {
+                if (name == BuiltInName::imageStore_0e1C3D)
+                {
+                    return &BuiltInFunction::kFunction_imageStore_0e1C3D;
+                }
+                break;
+            }
+            case 0x148f6fe1u:
+            {
+                if (name == BuiltInName::usubBorrow_0D0D0D)
+                {
+                    return &BuiltInFunction::kFunction_usubBorrow_0D0D0D;
+                }
+                break;
+            }
+            case 0x148f864bu:
+            {
+                if (name.beginsWith(BuiltInName::imageStore))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_imageStore_0h2C3D;
+                }
+                break;
+            }
+            case 0x148fd5f1u:
+            {
+                if (name.beginsWith(BuiltInName::imageStore))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_imageStore_0i2C3B;
+                }
+                break;
+            }
+            case 0x187b7b7cu:
+            {
+                if (name.beginsWith(BuiltInName::packSnorm4x8))
+                {
+                    ASSERT(name.length() == 15);
+                    return &BuiltInFunction::kFunction_packSnorm4x8_3B;
+                }
+                break;
+            }
+            case 0x187c1f3fu:
+            {
+                if (name.beginsWith(BuiltInName::packUnorm4x8))
+                {
+                    ASSERT(name.length() == 15);
+                    return &BuiltInFunction::kFunction_packUnorm4x8_3B;
+                }
+                break;
+            }
+            case 0x18a851efu:
+            {
+                if (name == BuiltInName::imulExtended_2C2C2C2C)
+                {
+                    return &BuiltInFunction::kFunction_imulExtended_2C2C2C2C;
+                }
+                break;
+            }
+            case 0x18a93bdcu:
+            {
+                if (name == BuiltInName::umulExtended_0D0D0D0D)
+                {
+                    return &BuiltInFunction::kFunction_umulExtended_0D0D0D0D;
+                }
+                break;
+            }
+            case 0x18a94b63u:
+            {
+                if (name == BuiltInName::umulExtended_3D3D3D3D)
+                {
+                    return &BuiltInFunction::kFunction_umulExtended_3D3D3D3D;
+                }
+                break;
+            }
+            case 0x18aa71ceu:
+            {
+                if (name == BuiltInName::umulExtended_2D2D2D2D)
+                {
+                    return &BuiltInFunction::kFunction_umulExtended_2D2D2D2D;
+                }
+                break;
+            }
+            case 0x18ab4baeu:
+            {
+                if (name == BuiltInName::umulExtended_1D1D1D1D)
+                {
+                    return &BuiltInFunction::kFunction_umulExtended_1D1D1D1D;
+                }
+                break;
+            }
+            case 0x18ac1df0u:
+            {
+                if (name == BuiltInName::imulExtended_3C3C3C3C)
+                {
+                    return &BuiltInFunction::kFunction_imulExtended_3C3C3C3C;
+                }
+                break;
+            }
+            case 0x18ac377fu:
+            {
+                if (name == BuiltInName::imulExtended_0C0C0C0C)
+                {
+                    return &BuiltInFunction::kFunction_imulExtended_0C0C0C0C;
+                }
+                break;
+            }
+            case 0x18ae7b8cu:
+            {
+                if (name == BuiltInName::imulExtended_1C1C1C1C)
+                {
+                    return &BuiltInFunction::kFunction_imulExtended_1C1C1C1C;
+                }
+                break;
+            }
+            case 0x1a7538dfu:
+            {
+                if (name.beginsWith(BuiltInName::memoryBarrier))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_memoryBarrier_;
+                }
+                break;
+            }
+            case 0x1a805162u:
+            {
+                if (name.beginsWith(BuiltInName::atomicCounter))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_atomicCounter_0F;
+                }
+                break;
+            }
+            case 0x1a907855u:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_textureGather_0P1B;
+                }
+                break;
+            }
+            case 0x1a90d2c2u:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_textureGather_0U1B;
+                }
+                break;
+            }
+            case 0x1a92a1ceu:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_textureGather_0H1B;
+                }
+                break;
+            }
+            case 0x1a92e9e5u:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_textureGather_0a2B;
+                }
+                break;
+            }
+            case 0x1a93b6c9u:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_textureGather_0X2B;
+                }
+                break;
+            }
+            case 0x1a93d703u:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_textureGather_0W2B;
+                }
+                break;
+            }
+            case 0x1a9418e8u:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_textureGather_0S2B;
+                }
+                break;
+            }
+            case 0x1a94543du:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_textureGather_0K2B;
+                }
+                break;
+            }
+            case 0x1a960122u:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_textureGather_0Z1B;
+                }
+                break;
+            }
+            case 0x1a96f0e7u:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_textureGather_0b2B;
+                }
+                break;
+            }
+            case 0x1a973644u:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_textureGather_0R2B;
+                }
+                break;
+            }
+            case 0x1a979ae3u:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_textureGather_0J2B;
+                }
+                break;
+            }
+            case 0x1aa023e1u:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 20);
+                    return &BuiltInFunction::kFunction_textureGather_0U1B0C;
+                }
+                break;
+            }
+            case 0x1aa086cfu:
+            {
+                if (name == BuiltInName::textureGather_0P1B0C)
+                {
+                    return &BuiltInFunction::kFunction_textureGather_0P1B0C;
+                }
+                break;
+            }
+            case 0x1aa1ab43u:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 20);
+                    return &BuiltInFunction::kFunction_textureGather_0b2B0B;
+                }
+                break;
+            }
+            case 0x1aa1bc4cu:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 20);
+                    return &BuiltInFunction::kFunction_textureGather_0X2B0C;
+                }
+                break;
+            }
+            case 0x1aa3ef46u:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 20);
+                    return &BuiltInFunction::kFunction_textureGather_0S2B0C;
+                }
+                break;
+            }
+            case 0x1aa4986bu:
+            {
+                if (name == BuiltInName::textureGather_0J2B0C)
+                {
+                    return &BuiltInFunction::kFunction_textureGather_0J2B0C;
+                }
+                break;
+            }
+            case 0x1aa4c59du:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 20);
+                    return &BuiltInFunction::kFunction_textureGather_0H1B0C;
+                }
+                break;
+            }
+            case 0x1aa573ecu:
+            {
+                if (name == BuiltInName::textureGather_0a2B0B)
+                {
+                    return &BuiltInFunction::kFunction_textureGather_0a2B0B;
+                }
+                break;
+            }
+            case 0x1aa590bdu:
+            {
+                if (name == BuiltInName::textureGather_0R2B0C)
+                {
+                    return &BuiltInFunction::kFunction_textureGather_0R2B0C;
+                }
+                break;
+            }
+            case 0x1aa5f0c6u:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 20);
+                    return &BuiltInFunction::kFunction_textureGather_0Z1B0B;
+                }
+                break;
+            }
+            case 0x1aa6c806u:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 20);
+                    return &BuiltInFunction::kFunction_textureGather_0W2B0C;
+                }
+                break;
+            }
+            case 0x1aa78b86u:
+            {
+                if (name.beginsWith(BuiltInName::textureGather))
+                {
+                    ASSERT(name.length() == 20);
+                    return &BuiltInFunction::kFunction_textureGather_0K2B0C;
+                }
+                break;
+            }
+            case 0x1c894fb3u:
+            {
+                if (name.beginsWith(BuiltInName::unpackSnorm4x8))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_unpackSnorm4x8_0D;
+                }
+                break;
+            }
+            case 0x1c8be3bau:
+            {
+                if (name.beginsWith(BuiltInName::unpackUnorm4x8))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_unpackUnorm4x8_0D;
+                }
+                break;
+            }
+            case 0x1c9986beu:
+            {
+                if (name.beginsWith(BuiltInName::atomicExchange))
+                {
+                    ASSERT(name.length() == 19);
+                    return &BuiltInFunction::kFunction_atomicExchange_0D0D;
+                }
+                break;
+            }
+            case 0x1c9b5eecu:
+            {
+                if (name.beginsWith(BuiltInName::atomicExchange))
+                {
+                    ASSERT(name.length() == 19);
+                    return &BuiltInFunction::kFunction_atomicExchange_0C0C;
+                }
+                break;
+            }
+            case 0x1ca86085u:
+            {
+                if (name.beginsWith(BuiltInName::atomicCompSwap))
+                {
+                    ASSERT(name.length() == 21);
+                    return &BuiltInFunction::kFunction_atomicCompSwap_0C0C0C;
+                }
+                break;
+            }
+            case 0x1caa900cu:
+            {
+                if (name == BuiltInName::atomicCompSwap_0D0D0D)
+                {
+                    return &BuiltInFunction::kFunction_atomicCompSwap_0D0D0D;
+                }
+                break;
+            }
+            case 0x1cb84b0cu:
+            {
+                if (name == BuiltInName::bitfieldInsert_3D3D0C0C)
+                {
+                    return &BuiltInFunction::kFunction_bitfieldInsert_3D3D0C0C;
+                }
+                break;
+            }
+            case 0x1cb880bfu:
+            {
+                if (name == BuiltInName::bitfieldInsert_3C3C0C0C)
+                {
+                    return &BuiltInFunction::kFunction_bitfieldInsert_3C3C0C0C;
+                }
+                break;
+            }
+            case 0x1cb90fd0u:
+            {
+                if (name == BuiltInName::bitfieldInsert_1C1C0C0C)
+                {
+                    return &BuiltInFunction::kFunction_bitfieldInsert_1C1C0C0C;
+                }
+                break;
+            }
+            case 0x1cb9fb13u:
+            {
+                if (name == BuiltInName::bitfieldInsert_1D1D0C0C)
+                {
+                    return &BuiltInFunction::kFunction_bitfieldInsert_1D1D0C0C;
+                }
+                break;
+            }
+            case 0x1cbb43f5u:
+            {
+                if (name == BuiltInName::bitfieldInsert_0D0D0C0C)
+                {
+                    return &BuiltInFunction::kFunction_bitfieldInsert_0D0D0C0C;
+                }
+                break;
+            }
+            case 0x1cbb9db3u:
+            {
+                if (name == BuiltInName::bitfieldInsert_2D2D0C0C)
+                {
+                    return &BuiltInFunction::kFunction_bitfieldInsert_2D2D0C0C;
+                }
+                break;
+            }
+            case 0x1cbdf898u:
+            {
+                if (name == BuiltInName::bitfieldInsert_0C0C0C0C)
+                {
+                    return &BuiltInFunction::kFunction_bitfieldInsert_0C0C0C0C;
+                }
+                break;
+            }
+            case 0x1cbfaf73u:
+            {
+                if (name == BuiltInName::bitfieldInsert_2C2C0C0C)
+                {
+                    return &BuiltInFunction::kFunction_bitfieldInsert_2C2C0C0C;
+                }
+                break;
+            }
+            case 0x1e907f62u:
+            {
+                if (name.beginsWith(BuiltInName::bitfieldReverse))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_bitfieldReverse_3D;
+                }
+                break;
+            }
+            case 0x1e9088f7u:
+            {
+                if (name.beginsWith(BuiltInName::bitfieldReverse))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_bitfieldReverse_3C;
+                }
+                break;
+            }
+            case 0x1e91c654u:
+            {
+                if (name.beginsWith(BuiltInName::bitfieldReverse))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_bitfieldReverse_0C;
+                }
+                break;
+            }
+            case 0x1e91e675u:
+            {
+                if (name.beginsWith(BuiltInName::bitfieldReverse))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_bitfieldReverse_0D;
+                }
+                break;
+            }
+            case 0x1e96ddc2u:
+            {
+                if (name.beginsWith(BuiltInName::bitfieldReverse))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_bitfieldReverse_1D;
+                }
+                break;
+            }
+            case 0x1e970da3u:
+            {
+                if (name.beginsWith(BuiltInName::bitfieldReverse))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_bitfieldReverse_1C;
+                }
+                break;
+            }
+            case 0x1e9744d7u:
+            {
+                if (name.beginsWith(BuiltInName::bitfieldReverse))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_bitfieldReverse_2D;
+                }
+                break;
+            }
+            case 0x1e9797d2u:
+            {
+                if (name.beginsWith(BuiltInName::bitfieldReverse))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_bitfieldReverse_2C;
+                }
+                break;
+            }
+            case 0x1eb0c64fu:
+            {
+                if (name.beginsWith(BuiltInName::bitfieldExtract))
+                {
+                    ASSERT(name.length() == 22);
+                    return &BuiltInFunction::kFunction_bitfieldExtract_2C0C0C;
+                }
+                break;
+            }
+            case 0x1eb0f9fau:
+            {
+                if (name == BuiltInName::bitfieldExtract_0D0C0C)
+                {
+                    return &BuiltInFunction::kFunction_bitfieldExtract_0D0C0C;
+                }
+                break;
+            }
+            case 0x1eb12f29u:
+            {
+                if (name.beginsWith(BuiltInName::bitfieldExtract))
+                {
+                    ASSERT(name.length() == 22);
+                    return &BuiltInFunction::kFunction_bitfieldExtract_3D0C0C;
+                }
+                break;
+            }
+            case 0x1eb17d11u:
+            {
+                if (name.beginsWith(BuiltInName::bitfieldExtract))
+                {
+                    ASSERT(name.length() == 22);
+                    return &BuiltInFunction::kFunction_bitfieldExtract_3C0C0C;
+                }
+                break;
+            }
+            case 0x1eb17f7du:
+            {
+                if (name.beginsWith(BuiltInName::bitfieldExtract))
+                {
+                    ASSERT(name.length() == 22);
+                    return &BuiltInFunction::kFunction_bitfieldExtract_0C0C0C;
+                }
+                break;
+            }
+            case 0x1eb19a50u:
+            {
+                if (name == BuiltInName::bitfieldExtract_1C0C0C)
+                {
+                    return &BuiltInFunction::kFunction_bitfieldExtract_1C0C0C;
+                }
+                break;
+            }
+            case 0x1eb28b55u:
+            {
+                if (name.beginsWith(BuiltInName::bitfieldExtract))
+                {
+                    ASSERT(name.length() == 22);
+                    return &BuiltInFunction::kFunction_bitfieldExtract_2D0C0C;
+                }
+                break;
+            }
+            case 0x1eb5f0c8u:
+            {
+                if (name.beginsWith(BuiltInName::bitfieldExtract))
+                {
+                    ASSERT(name.length() == 22);
+                    return &BuiltInFunction::kFunction_bitfieldExtract_1D0C0C;
+                }
+                break;
+            }
+            case 0x249e7359u:
+            {
+                if (name.beginsWith(BuiltInName::memoryBarrierImage))
+                {
+                    ASSERT(name.length() == 19);
+                    return &BuiltInFunction::kFunction_memoryBarrierImage_;
+                }
+                break;
+            }
+            case 0x26a7e24bu:
+            {
+                if (name.beginsWith(BuiltInName::memoryBarrierBuffer))
+                {
+                    ASSERT(name.length() == 20);
+                    return &BuiltInFunction::kFunction_memoryBarrierBuffer_;
+                }
+                break;
+            }
+            case 0x26d1d7a3u:
+            {
+                if (name.beginsWith(BuiltInName::textureGatherOffset))
+                {
+                    ASSERT(name.length() == 26);
+                    return &BuiltInFunction::kFunction_textureGatherOffset_0P1B1C;
+                }
+                break;
+            }
+            case 0x26d1f440u:
+            {
+                if (name.beginsWith(BuiltInName::textureGatherOffset))
+                {
+                    ASSERT(name.length() == 26);
+                    return &BuiltInFunction::kFunction_textureGatherOffset_0K2B1C;
+                }
+                break;
+            }
+            case 0x26d29f74u:
+            {
+                if (name.beginsWith(BuiltInName::textureGatherOffset))
+                {
+                    ASSERT(name.length() == 26);
+                    return &BuiltInFunction::kFunction_textureGatherOffset_0S2B1C;
+                }
+                break;
+            }
+            case 0x26d701d7u:
+            {
+                if (name.beginsWith(BuiltInName::textureGatherOffset))
+                {
+                    ASSERT(name.length() == 26);
+                    return &BuiltInFunction::kFunction_textureGatherOffset_0X2B1C;
+                }
+                break;
+            }
+            case 0x26d71952u:
+            {
+                if (name.beginsWith(BuiltInName::textureGatherOffset))
+                {
+                    ASSERT(name.length() == 26);
+                    return &BuiltInFunction::kFunction_textureGatherOffset_0H1B1C;
+                }
+                break;
+            }
+            case 0x26d7dce7u:
+            {
+                if (name == BuiltInName::textureGatherOffset_0U1B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureGatherOffset_0U1B1C;
+                }
+                break;
+            }
+            case 0x26e015c9u:
+            {
+                if (name == BuiltInName::textureGatherOffset_0S2B1C0C)
+                {
+                    return &BuiltInFunction::kFunction_textureGatherOffset_0S2B1C0C;
+                }
+                break;
+            }
+            case 0x26e1df8cu:
+            {
+                if (name == BuiltInName::textureGatherOffset_0X2B1C0C)
+                {
+                    return &BuiltInFunction::kFunction_textureGatherOffset_0X2B1C0C;
+                }
+                break;
+            }
+            case 0x26e2cb51u:
+            {
+                if (name == BuiltInName::textureGatherOffset_0U1B1C0C)
+                {
+                    return &BuiltInFunction::kFunction_textureGatherOffset_0U1B1C0C;
+                }
+                break;
+            }
+            case 0x26e459f8u:
+            {
+                if (name == BuiltInName::textureGatherOffset_0K2B1C0C)
+                {
+                    return &BuiltInFunction::kFunction_textureGatherOffset_0K2B1C0C;
+                }
+                break;
+            }
+            case 0x26e476d0u:
+            {
+                if (name == BuiltInName::textureGatherOffset_0H1B1C0C)
+                {
+                    return &BuiltInFunction::kFunction_textureGatherOffset_0H1B1C0C;
+                }
+                break;
+            }
+            case 0x26e596a4u:
+            {
+                if (name == BuiltInName::textureGatherOffset_0Z1B0B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureGatherOffset_0Z1B0B1C;
+                }
+                break;
+            }
+            case 0x26e5b6bdu:
+            {
+                if (name == BuiltInName::textureGatherOffset_0P1B1C0C)
+                {
+                    return &BuiltInFunction::kFunction_textureGatherOffset_0P1B1C0C;
+                }
+                break;
+            }
+            case 0x26e6991bu:
+            {
+                if (name == BuiltInName::textureGatherOffset_0b2B0B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureGatherOffset_0b2B0B1C;
+                }
+                break;
+            }
+            case 0x2ccf8f34u:
+            {
+                if (name.beginsWith(BuiltInName::atomicCounterIncrement))
+                {
+                    ASSERT(name.length() == 25);
+                    return &BuiltInFunction::kFunction_atomicCounterIncrement_0F;
+                }
+                break;
+            }
+            case 0x2ccfbbbeu:
+            {
+                if (name.beginsWith(BuiltInName::atomicCounterDecrement))
+                {
+                    ASSERT(name.length() == 25);
+                    return &BuiltInFunction::kFunction_atomicCounterDecrement_0F;
+                }
+                break;
+            }
+            case 0x34ded18du:
+            {
+                if (name.beginsWith(BuiltInName::memoryBarrierAtomicCounter))
+                {
+                    ASSERT(name.length() == 27);
+                    return &BuiltInFunction::kFunction_memoryBarrierAtomicCounter_;
+                }
+                break;
+            }
+            case 0x7e2bef7au:
+            {
+                if (name == BuiltInName::gl_in)
+                {
+                    // Only initialized if shaderType == GL_GEOMETRY_SHADER_EXT
+                    return mVar_gl_in;
+                }
+                break;
+            }
+            case 0x7e8166efu:
+            {
+                if (name == BuiltInName::gl_MaxImageUnits)
+                {
+                    return mVar_gl_MaxImageUnits;
+                }
+                break;
+            }
+            case 0x7ecf4a1bu:
+            {
+                if (name == BuiltInName::gl_MaxVertexImageUniforms)
+                {
+                    return mVar_gl_MaxVertexImageUniforms;
+                }
+                break;
+            }
+            case 0x7ed27574u:
+            {
+                if (name == BuiltInName::gl_MaxVertexAtomicCounters)
+                {
+                    return mVar_gl_MaxVertexAtomicCounters;
+                }
+                break;
+            }
+            case 0x7ed2bd5cu:
+            {
+                if (name == BuiltInName::gl_MaxComputeImageUniforms)
+                {
+                    return mVar_gl_MaxComputeImageUniforms;
+                }
+                break;
+            }
+            case 0x7ed77973u:
+            {
+                if (name == BuiltInName::gl_MaxComputeWorkGroupSize)
+                {
+                    return mVar_gl_MaxComputeWorkGroupSize;
+                }
+                break;
+            }
+            case 0x7ed9ae57u:
+            {
+                if (name == BuiltInName::gl_MaxCombinedImageUniforms)
+                {
+                    return mVar_gl_MaxCombinedImageUniforms;
+                }
+                break;
+            }
+            case 0x7ed9f437u:
+            {
+                if (name == BuiltInName::gl_MaxGeometryImageUniforms)
+                {
+                    return mVar_gl_MaxGeometryImageUniforms;
+                }
+                break;
+            }
+            case 0x7edacc17u:
+            {
+                if (name == BuiltInName::gl_MaxAtomicCounterBindings)
+                {
+                    return mVar_gl_MaxAtomicCounterBindings;
+                }
+                break;
+            }
+            case 0x7ede0db3u:
+            {
+                if (name == BuiltInName::gl_MaxComputeAtomicCounters)
+                {
+                    return mVar_gl_MaxComputeAtomicCounters;
+                }
+                break;
+            }
+            case 0x7edeadeeu:
+            {
+                if (name == BuiltInName::gl_MaxComputeWorkGroupCount)
+                {
+                    return mVar_gl_MaxComputeWorkGroupCount;
+                }
+                break;
+            }
+            case 0x7edf534au:
+            {
+                if (name == BuiltInName::gl_MaxFragmentImageUniforms)
+                {
+                    return mVar_gl_MaxFragmentImageUniforms;
+                }
+                break;
+            }
+            case 0x7ee1b439u:
+            {
+                if (name == BuiltInName::gl_MaxGeometryOutputVertices)
+                {
+                    return mVar_gl_MaxGeometryOutputVertices;
+                }
+                break;
+            }
+            case 0x7ee23dcau:
+            {
+                if (name == BuiltInName::gl_MaxFragmentAtomicCounters)
+                {
+                    return mVar_gl_MaxFragmentAtomicCounters;
+                }
+                break;
+            }
+            case 0x7ee400c5u:
+            {
+                if (name == BuiltInName::gl_MaxCombinedAtomicCounters)
+                {
+                    return mVar_gl_MaxCombinedAtomicCounters;
+                }
+                break;
+            }
+            case 0x7ee6d3cfu:
+            {
+                if (name == BuiltInName::gl_MaxGeometryAtomicCounters)
+                {
+                    return mVar_gl_MaxGeometryAtomicCounters;
+                }
+                break;
+            }
+            case 0x7eec3ae1u:
+            {
+                if (name == BuiltInName::gl_MaxGeometryInputComponents)
+                {
+                    return mVar_gl_MaxGeometryInputComponents;
+                }
+                break;
+            }
+            case 0x7eecdfadu:
+            {
+                if (name == BuiltInName::gl_MaxAtomicCounterBufferSize)
+                {
+                    return mVar_gl_MaxAtomicCounterBufferSize;
+                }
+                break;
+            }
+            case 0x7ef00fc2u:
+            {
+                if (name == BuiltInName::gl_MaxComputeTextureImageUnits)
+                {
+                    return mVar_gl_MaxComputeTextureImageUnits;
+                }
+                break;
+            }
+            case 0x7ef3740bu:
+            {
+                if (name == BuiltInName::gl_MaxComputeUniformComponents)
+                {
+                    return mVar_gl_MaxComputeUniformComponents;
+                }
+                break;
+            }
+            case 0x7ef69ab4u:
+            {
+                if (name == BuiltInName::gl_MaxGeometryOutputComponents)
+                {
+                    return mVar_gl_MaxGeometryOutputComponents;
+                }
+                break;
+            }
+            case 0x7ef9b17du:
+            {
+                if (name == BuiltInName::gl_MaxGeometryTextureImageUnits)
+                {
+                    return mVar_gl_MaxGeometryTextureImageUnits;
+                }
+                break;
+            }
+            case 0x7efe1865u:
+            {
+                if (name == BuiltInName::gl_MaxGeometryUniformComponents)
+                {
+                    return mVar_gl_MaxGeometryUniformComponents;
+                }
+                break;
+            }
+            case 0x7f008375u:
+            {
+                if (name == BuiltInName::gl_MaxVertexAtomicCounterBuffers)
+                {
+                    return mVar_gl_MaxVertexAtomicCounterBuffers;
+                }
+                break;
+            }
+            case 0x7f0d626fu:
+            {
+                if (name == BuiltInName::gl_MaxComputeAtomicCounterBuffers)
+                {
+                    return mVar_gl_MaxComputeAtomicCounterBuffers;
+                }
+                break;
+            }
+            case 0x7f11e359u:
+            {
+                if (name == BuiltInName::gl_MaxCombinedAtomicCounterBuffers)
+                {
+                    return mVar_gl_MaxCombinedAtomicCounterBuffers;
+                }
+                break;
+            }
+            case 0x7f170f84u:
+            {
+                if (name == BuiltInName::gl_MaxGeometryAtomicCounterBuffers)
+                {
+                    return mVar_gl_MaxGeometryAtomicCounterBuffers;
+                }
+                break;
+            }
+            case 0x7f17bd18u:
+            {
+                if (name == BuiltInName::gl_MaxFragmentAtomicCounterBuffers)
+                {
+                    return mVar_gl_MaxFragmentAtomicCounterBuffers;
+                }
+                break;
+            }
+            case 0x7f1c60f8u:
+            {
+                if (name == BuiltInName::gl_MaxCombinedShaderOutputResources)
+                {
+                    return mVar_gl_MaxCombinedShaderOutputResources;
+                }
+                break;
+            }
+            case 0x7f1cd073u:
+            {
+                if (name == BuiltInName::gl_MaxGeometryTotalOutputComponents)
+                {
+                    return mVar_gl_MaxGeometryTotalOutputComponents;
+                }
+                break;
+            }
+        }
+        if (mShaderType == GL_COMPUTE_SHADER)
+        {
+            switch (nameHash)
+            {
+                case 0x0e41a660u:
+                {
+                    if (name.beginsWith(BuiltInName::barrier))
+                    {
+                        ASSERT(name.length() == 8);
+                        return &BuiltInFunction::kFunction_barrier_;
+                    }
+                    break;
+                }
+                case 0x249ee97cu:
+                {
+                    if (name.beginsWith(BuiltInName::groupMemoryBarrier))
+                    {
+                        ASSERT(name.length() == 19);
+                        return &BuiltInFunction::kFunction_groupMemoryBarrier_;
+                    }
+                    break;
+                }
+                case 0x26a4d8e6u:
+                {
+                    if (name.beginsWith(BuiltInName::memoryBarrierShared))
+                    {
+                        ASSERT(name.length() == 20);
+                        return &BuiltInFunction::kFunction_memoryBarrierShared_;
+                    }
+                    break;
+                }
+                case 0x7e736b62u:
+                {
+                    if (name == BuiltInName::gl_WorkGroupID)
+                    {
+                        return &BuiltInVariable::kVar_gl_WorkGroupID;
+                    }
+                    break;
+                }
+                case 0x7e808e8fu:
+                {
+                    if (name == BuiltInName::gl_WorkGroupSize)
+                    {
+                        return &BuiltInVariable::kVar_gl_WorkGroupSize;
+                    }
+                    break;
+                }
+                case 0x7e82b146u:
+                {
+                    if (name == BuiltInName::gl_NumWorkGroups)
+                    {
+                        return &BuiltInVariable::kVar_gl_NumWorkGroups;
+                    }
+                    break;
+                }
+                case 0x7ea251edu:
+                {
+                    if (name == BuiltInName::gl_LocalInvocationID)
+                    {
+                        return &BuiltInVariable::kVar_gl_LocalInvocationID;
+                    }
+                    break;
+                }
+                case 0x7ead13a8u:
+                {
+                    if (name == BuiltInName::gl_GlobalInvocationID)
+                    {
+                        return &BuiltInVariable::kVar_gl_GlobalInvocationID;
+                    }
+                    break;
+                }
+                case 0x7ebcd395u:
+                {
+                    if (name == BuiltInName::gl_LocalInvocationIndex)
+                    {
+                        return &BuiltInVariable::kVar_gl_LocalInvocationIndex;
+                    }
+                    break;
+                }
+            }
+        }
+        if (mShaderType == GL_GEOMETRY_SHADER_EXT)
+        {
+            switch (nameHash)
+            {
+                case 0x145d55c9u:
+                {
+                    if (name.beginsWith(BuiltInName::EmitVertex))
+                    {
+                        ASSERT(name.length() == 11);
+                        return &BuiltInFunction::kFunction_EmitVertex_;
+                    }
+                    break;
+                }
+                case 0x186fcde2u:
+                {
+                    if (name.beginsWith(BuiltInName::EndPrimitive))
+                    {
+                        ASSERT(name.length() == 13);
+                        return &BuiltInFunction::kFunction_EndPrimitive_;
+                    }
+                    break;
+                }
+                case 0x7e400f84u:
+                {
+                    if (name == BuiltInName::gl_Layer)
+                    {
+                        return &BuiltInVariable::kVar_gl_LayerGS;
+                    }
+                    break;
+                }
+                case 0x7e580bc5u:
+                {
+                    if (name == BuiltInName::gl_Position)
+                    {
+                        return mVar_gl_PositionGS;
+                    }
+                    break;
+                }
+                case 0x7e67167au:
+                {
+                    if (name == BuiltInName::gl_PerVertex)
+                    {
+                        return mVar_gl_PerVertex;
+                    }
+                    break;
+                }
+                case 0x7e742076u:
+                {
+                    if (name == BuiltInName::gl_PrimitiveID)
+                    {
+                        return &BuiltInVariable::kVar_gl_PrimitiveIDGS;
+                    }
+                    break;
+                }
+                case 0x7e7fe684u:
+                {
+                    if (name == BuiltInName::gl_InvocationID)
+                    {
+                        return &BuiltInVariable::kVar_gl_InvocationID;
+                    }
+                    break;
+                }
+                case 0x7e865240u:
+                {
+                    if (name == BuiltInName::gl_PrimitiveIDIn)
+                    {
+                        return &BuiltInVariable::kVar_gl_PrimitiveIDIn;
+                    }
+                    break;
+                }
+            }
+        }
+        if ((mShaderType == GL_FRAGMENT_SHADER) && (mResources.EXT_geometry_shader))
+        {
+            switch (nameHash)
+            {
+                case 0x7e400f84u:
+                {
+                    if (name == BuiltInName::gl_Layer)
+                    {
+                        return &BuiltInVariable::kVar_gl_Layer;
+                    }
+                    break;
+                }
+                case 0x7e742076u:
+                {
+                    if (name == BuiltInName::gl_PrimitiveID)
+                    {
+                        return &BuiltInVariable::kVar_gl_PrimitiveID;
+                    }
+                    break;
+                }
+            }
+        }
+    }
+    if (shaderVersion >= 300)
+    {
+        switch (nameHash)
+        {
+            case 0x06309dbcu:
+            {
+                if (name.beginsWith(BuiltInName::abs))
+                {
+                    ASSERT(name.length() == 6);
+                    return &BuiltInFunction::kFunction_abs_0C;
+                }
+                break;
+            }
+            case 0x0631d85fu:
+            {
+                if (name.beginsWith(BuiltInName::abs))
+                {
+                    ASSERT(name.length() == 6);
+                    return &BuiltInFunction::kFunction_abs_3C;
+                }
+                break;
+            }
+            case 0x06370c70u:
+            {
+                if (name.beginsWith(BuiltInName::abs))
+                {
+                    ASSERT(name.length() == 6);
+                    return &BuiltInFunction::kFunction_abs_2C;
+                }
+                break;
+            }
+            case 0x06378eb0u:
+            {
+                if (name.beginsWith(BuiltInName::abs))
+                {
+                    ASSERT(name.length() == 6);
+                    return &BuiltInFunction::kFunction_abs_1C;
+                }
+                break;
+            }
+            case 0x06408ba2u:
+            {
+                if (name.beginsWith(BuiltInName::min))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_min_2D0D;
+                }
+                break;
+            }
+            case 0x0640f128u:
+            {
+                if (name.beginsWith(BuiltInName::max))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_max_1C0C;
+                }
+                break;
+            }
+            case 0x06420bb0u:
+            {
+                if (name.beginsWith(BuiltInName::min))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_min_0D0D;
+                }
+                break;
+            }
+            case 0x064236d1u:
+            {
+                if (name.beginsWith(BuiltInName::min))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_min_2D2D;
+                }
+                break;
+            }
+            case 0x06425522u:
+            {
+                if (name.beginsWith(BuiltInName::min))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_min_3C0C;
+                }
+                break;
+            }
+            case 0x06425db3u:
+            {
+                if (name.beginsWith(BuiltInName::min))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_min_2C0C;
+                }
+                break;
+            }
+            case 0x06429550u:
+            {
+                if (name.beginsWith(BuiltInName::max))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_max_2D2D;
+                }
+                break;
+            }
+            case 0x06429e9cu:
+            {
+                if (name.beginsWith(BuiltInName::max))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_max_2C0C;
+                }
+                break;
+            }
+            case 0x0642c869u:
+            {
+                if (name.beginsWith(BuiltInName::max))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_max_3D3D;
+                }
+                break;
+            }
+            case 0x0642dbfeu:
+            {
+                if (name.beginsWith(BuiltInName::min))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_min_3C3C;
+                }
+                break;
+            }
+            case 0x064305b5u:
+            {
+                if (name.beginsWith(BuiltInName::min))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_min_3D3D;
+                }
+                break;
+            }
+            case 0x06436c9au:
+            {
+                if (name.beginsWith(BuiltInName::min))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_min_1D0D;
+                }
+                break;
+            }
+            case 0x0643ebd5u:
+            {
+                if (name.beginsWith(BuiltInName::min))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_min_3D0D;
+                }
+                break;
+            }
+            case 0x06441467u:
+            {
+                if (name.beginsWith(BuiltInName::min))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_min_2C2C;
+                }
+                break;
+            }
+            case 0x0644176eu:
+            {
+                if (name.beginsWith(BuiltInName::min))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_min_1C1C;
+                }
+                break;
+            }
+            case 0x06443b94u:
+            {
+                if (name.beginsWith(BuiltInName::max))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_max_2D0D;
+                }
+                break;
+            }
+            case 0x06448798u:
+            {
+                if (name.beginsWith(BuiltInName::max))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_max_3C3C;
+                }
+                break;
+            }
+            case 0x0644a6dfu:
+            {
+                if (name.beginsWith(BuiltInName::min))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_min_1D1D;
+                }
+                break;
+            }
+            case 0x0644cd73u:
+            {
+                if (name.beginsWith(BuiltInName::max))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_max_2C2C;
+                }
+                break;
+            }
+            case 0x06450593u:
+            {
+                if (name.beginsWith(BuiltInName::min))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_min_1C0C;
+                }
+                break;
+            }
+            case 0x06452105u:
+            {
+                if (name.beginsWith(BuiltInName::max))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_max_1D0D;
+                }
+                break;
+            }
+            case 0x06454045u:
+            {
+                if (name.beginsWith(BuiltInName::max))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_max_0C0C;
+                }
+                break;
+            }
+            case 0x0645e25du:
+            {
+                if (name.beginsWith(BuiltInName::min))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_min_0C0C;
+                }
+                break;
+            }
+            case 0x06460349u:
+            {
+                if (name.beginsWith(BuiltInName::max))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_max_1D1D;
+                }
+                break;
+            }
+            case 0x06472b16u:
+            {
+                if (name.beginsWith(BuiltInName::max))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_max_3D0D;
+                }
+                break;
+            }
+            case 0x06473146u:
+            {
+                if (name.beginsWith(BuiltInName::max))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_max_0D0D;
+                }
+                break;
+            }
+            case 0x06475b89u:
+            {
+                if (name.beginsWith(BuiltInName::max))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_max_3C0C;
+                }
+                break;
+            }
+            case 0x0647bc75u:
+            {
+                if (name.beginsWith(BuiltInName::max))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_max_1C1C;
+                }
+                break;
+            }
+            case 0x0654b2f8u:
+            {
+                if (name.beginsWith(BuiltInName::mix))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_mix_2B2B2E;
+                }
+                break;
+            }
+            case 0x0655a7e2u:
+            {
+                if (name == BuiltInName::mix_0B0B0E)
+                {
+                    return &BuiltInFunction::kFunction_mix_0B0B0E;
+                }
+                break;
+            }
+            case 0x06567d08u:
+            {
+                if (name.beginsWith(BuiltInName::mix))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_mix_3B3B3E;
+                }
+                break;
+            }
+            case 0x0657f3adu:
+            {
+                if (name.beginsWith(BuiltInName::mix))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_mix_1B1B1E;
+                }
+                break;
+            }
+            case 0x0838025eu:
+            {
+                if (name.beginsWith(BuiltInName::tanh))
+                {
+                    ASSERT(name.length() == 7);
+                    return &BuiltInFunction::kFunction_tanh_3B;
+                }
+                break;
+            }
+            case 0x0838944cu:
+            {
+                if (name.beginsWith(BuiltInName::tanh))
+                {
+                    ASSERT(name.length() == 7);
+                    return &BuiltInFunction::kFunction_tanh_0B;
+                }
+                break;
+            }
+            case 0x08392747u:
+            {
+                if (name.beginsWith(BuiltInName::sinh))
+                {
+                    ASSERT(name.length() == 7);
+                    return &BuiltInFunction::kFunction_sinh_2B;
+                }
+                break;
+            }
+            case 0x08398f4au:
+            {
+                if (name.beginsWith(BuiltInName::sinh))
+                {
+                    ASSERT(name.length() == 7);
+                    return &BuiltInFunction::kFunction_sinh_1B;
+                }
+                break;
+            }
+            case 0x083991ddu:
+            {
+                if (name.beginsWith(BuiltInName::tanh))
+                {
+                    ASSERT(name.length() == 7);
+                    return &BuiltInFunction::kFunction_tanh_1B;
+                }
+                break;
+            }
+            case 0x083aa373u:
+            {
+                if (name.beginsWith(BuiltInName::sinh))
+                {
+                    ASSERT(name.length() == 7);
+                    return &BuiltInFunction::kFunction_sinh_0B;
+                }
+                break;
+            }
+            case 0x083acb5eu:
+            {
+                if (name.beginsWith(BuiltInName::tanh))
+                {
+                    ASSERT(name.length() == 7);
+                    return &BuiltInFunction::kFunction_tanh_2B;
+                }
+                break;
+            }
+            case 0x083acbf5u:
+            {
+                if (name.beginsWith(BuiltInName::sign))
+                {
+                    ASSERT(name.length() == 7);
+                    return &BuiltInFunction::kFunction_sign_1C;
+                }
+                break;
+            }
+            case 0x083b5c45u:
+            {
+                if (name.beginsWith(BuiltInName::cosh))
+                {
+                    ASSERT(name.length() == 7);
+                    return &BuiltInFunction::kFunction_cosh_0B;
+                }
+                break;
+            }
+            case 0x083bd9f8u:
+            {
+                if (name.beginsWith(BuiltInName::sinh))
+                {
+                    ASSERT(name.length() == 7);
+                    return &BuiltInFunction::kFunction_sinh_3B;
+                }
+                break;
+            }
+            case 0x083c1656u:
+            {
+                if (name.beginsWith(BuiltInName::sign))
+                {
+                    ASSERT(name.length() == 7);
+                    return &BuiltInFunction::kFunction_sign_2C;
+                }
+                break;
+            }
+            case 0x083c57c4u:
+            {
+                if (name.beginsWith(BuiltInName::cosh))
+                {
+                    ASSERT(name.length() == 7);
+                    return &BuiltInFunction::kFunction_cosh_1B;
+                }
+                break;
+            }
+            case 0x083d503bu:
+            {
+                if (name.beginsWith(BuiltInName::sign))
+                {
+                    ASSERT(name.length() == 7);
+                    return &BuiltInFunction::kFunction_sign_3C;
+                }
+                break;
+            }
+            case 0x083d8227u:
+            {
+                if (name.beginsWith(BuiltInName::cosh))
+                {
+                    ASSERT(name.length() == 7);
+                    return &BuiltInFunction::kFunction_cosh_2B;
+                }
+                break;
+            }
+            case 0x083dd369u:
+            {
+                if (name.beginsWith(BuiltInName::sign))
+                {
+                    ASSERT(name.length() == 7);
+                    return &BuiltInFunction::kFunction_sign_0C;
+                }
+                break;
+            }
+            case 0x083ed2deu:
+            {
+                if (name.beginsWith(BuiltInName::cosh))
+                {
+                    ASSERT(name.length() == 7);
+                    return &BuiltInFunction::kFunction_cosh_3B;
+                }
+                break;
+            }
+            case 0x084807e9u:
+            {
+                if (name.beginsWith(BuiltInName::modf))
+                {
+                    ASSERT(name.length() == 9);
+                    return &BuiltInFunction::kFunction_modf_3B3B;
+                }
+                break;
+            }
+            case 0x084a908au:
+            {
+                if (name.beginsWith(BuiltInName::modf))
+                {
+                    ASSERT(name.length() == 9);
+                    return &BuiltInFunction::kFunction_modf_1B1B;
+                }
+                break;
+            }
+            case 0x084bf445u:
+            {
+                if (name.beginsWith(BuiltInName::modf))
+                {
+                    ASSERT(name.length() == 9);
+                    return &BuiltInFunction::kFunction_modf_0B0B;
+                }
+                break;
+            }
+            case 0x084fa835u:
+            {
+                if (name.beginsWith(BuiltInName::modf))
+                {
+                    ASSERT(name.length() == 9);
+                    return &BuiltInFunction::kFunction_modf_2B2B;
+                }
+                break;
+            }
+            case 0x0a400148u:
+            {
+                if (name.beginsWith(BuiltInName::asinh))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_asinh_2B;
+                }
+                break;
+            }
+            case 0x0a406460u:
+            {
+                if (name.beginsWith(BuiltInName::isnan))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_isnan_2B;
+                }
+                break;
+            }
+            case 0x0a407c52u:
+            {
+                if (name.beginsWith(BuiltInName::round))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_round_0B;
+                }
+                break;
+            }
+            case 0x0a412446u:
+            {
+                if (name.beginsWith(BuiltInName::trunc))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_trunc_0B;
+                }
+                break;
+            }
+            case 0x0a4125d1u:
+            {
+                if (name.beginsWith(BuiltInName::asinh))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_asinh_3B;
+                }
+                break;
+            }
+            case 0x0a4189d9u:
+            {
+                if (name.beginsWith(BuiltInName::round))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_round_3B;
+                }
+                break;
+            }
+            case 0x0a41bc4bu:
+            {
+                if (name.beginsWith(BuiltInName::trunc))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_trunc_3B;
+                }
+                break;
+            }
+            case 0x0a4262ceu:
+            {
+                if (name.beginsWith(BuiltInName::isinf))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_isinf_2B;
+                }
+                break;
+            }
+            case 0x0a42b872u:
+            {
+                if (name.beginsWith(BuiltInName::trunc))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_trunc_2B;
+                }
+                break;
+            }
+            case 0x0a430643u:
+            {
+                if (name.beginsWith(BuiltInName::atanh))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_atanh_2B;
+                }
+                break;
+            }
+            case 0x0a43b397u:
+            {
+                if (name.beginsWith(BuiltInName::isinf))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_isinf_3B;
+                }
+                break;
+            }
+            case 0x0a43edf9u:
+            {
+                if (name.beginsWith(BuiltInName::trunc))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_trunc_1B;
+                }
+                break;
+            }
+            case 0x0a4431a8u:
+            {
+                if (name.beginsWith(BuiltInName::atanh))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_atanh_1B;
+                }
+                break;
+            }
+            case 0x0a443a26u:
+            {
+                if (name.beginsWith(BuiltInName::isinf))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_isinf_0B;
+                }
+                break;
+            }
+            case 0x0a44ad91u:
+            {
+                if (name.beginsWith(BuiltInName::acosh))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_acosh_1B;
+                }
+                break;
+            }
+            case 0x0a452617u:
+            {
+                if (name.beginsWith(BuiltInName::isinf))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_isinf_1B;
+                }
+                break;
+            }
+            case 0x0a4561b0u:
+            {
+                if (name.beginsWith(BuiltInName::isnan))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_isnan_3B;
+                }
+                break;
+            }
+            case 0x0a4582c9u:
+            {
+                if (name.beginsWith(BuiltInName::atanh))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_atanh_0B;
+                }
+                break;
+            }
+            case 0x0a45fcfdu:
+            {
+                if (name.beginsWith(BuiltInName::atanh))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_atanh_3B;
+                }
+                break;
+            }
+            case 0x0a461d10u:
+            {
+                if (name.beginsWith(BuiltInName::acosh))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_acosh_0B;
+                }
+                break;
+            }
+            case 0x0a464ad3u:
+            {
+                if (name.beginsWith(BuiltInName::asinh))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_asinh_0B;
+                }
+                break;
+            }
+            case 0x0a46778au:
+            {
+                if (name.beginsWith(BuiltInName::acosh))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_acosh_3B;
+                }
+                break;
+            }
+            case 0x0a46ab3bu:
+            {
+                if (name.beginsWith(BuiltInName::isnan))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_isnan_0B;
+                }
+                break;
+            }
+            case 0x0a46f2d2u:
+            {
+                if (name.beginsWith(BuiltInName::round))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_round_2B;
+                }
+                break;
+            }
+            case 0x0a4758c8u:
+            {
+                if (name.beginsWith(BuiltInName::round))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_round_1B;
+                }
+                break;
+            }
+            case 0x0a478c93u:
+            {
+                if (name.beginsWith(BuiltInName::acosh))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_acosh_2B;
+                }
+                break;
+            }
+            case 0x0a47bb52u:
+            {
+                if (name.beginsWith(BuiltInName::asinh))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_asinh_1B;
+                }
+                break;
+            }
+            case 0x0a47fa7au:
+            {
+                if (name.beginsWith(BuiltInName::isnan))
+                {
+                    ASSERT(name.length() == 8);
+                    return &BuiltInFunction::kFunction_isnan_1B;
+                }
+                break;
+            }
+            case 0x0a524bc4u:
+            {
+                if (name.beginsWith(BuiltInName::equal))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_equal_2D2D;
+                }
+                break;
+            }
+            case 0x0a5613e7u:
+            {
+                if (name.beginsWith(BuiltInName::equal))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_equal_1D1D;
+                }
+                break;
+            }
+            case 0x0a56ba24u:
+            {
+                if (name.beginsWith(BuiltInName::equal))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_equal_3D3D;
+                }
+                break;
+            }
+            case 0x0a601dd8u:
+            {
+                if (name == BuiltInName::clamp_2C2C2C)
+                {
+                    return &BuiltInFunction::kFunction_clamp_2C2C2C;
+                }
+                break;
+            }
+            case 0x0a60570du:
+            {
+                if (name.beginsWith(BuiltInName::clamp))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_clamp_1D0D0D;
+                }
+                break;
+            }
+            case 0x0a60d0c5u:
+            {
+                if (name == BuiltInName::clamp_1C0C0C)
+                {
+                    return &BuiltInFunction::kFunction_clamp_1C0C0C;
+                }
+                break;
+            }
+            case 0x0a621a2bu:
+            {
+                if (name.beginsWith(BuiltInName::clamp))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_clamp_0C0C0C;
+                }
+                break;
+            }
+            case 0x0a623042u:
+            {
+                if (name.beginsWith(BuiltInName::clamp))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_clamp_2D0D0D;
+                }
+                break;
+            }
+            case 0x0a624f01u:
+            {
+                if (name == BuiltInName::clamp_3C0C0C)
+                {
+                    return &BuiltInFunction::kFunction_clamp_3C0C0C;
+                }
+                break;
+            }
+            case 0x0a62ab50u:
+            {
+                if (name == BuiltInName::clamp_1C1C1C)
+                {
+                    return &BuiltInFunction::kFunction_clamp_1C1C1C;
+                }
+                break;
+            }
+            case 0x0a631d0bu:
+            {
+                if (name.beginsWith(BuiltInName::clamp))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_clamp_1D1D1D;
+                }
+                break;
+            }
+            case 0x0a64f567u:
+            {
+                if (name.beginsWith(BuiltInName::clamp))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_clamp_2D2D2D;
+                }
+                break;
+            }
+            case 0x0a656274u:
+            {
+                if (name.beginsWith(BuiltInName::clamp))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_clamp_3C3C3C;
+                }
+                break;
+            }
+            case 0x0a65a625u:
+            {
+                if (name == BuiltInName::clamp_3D0D0D)
+                {
+                    return &BuiltInFunction::kFunction_clamp_3D0D0D;
+                }
+                break;
+            }
+            case 0x0a660047u:
+            {
+                if (name.beginsWith(BuiltInName::clamp))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_clamp_2C0C0C;
+                }
+                break;
+            }
+            case 0x0a660f60u:
+            {
+                if (name == BuiltInName::clamp_0D0D0D)
+                {
+                    return &BuiltInFunction::kFunction_clamp_0D0D0D;
+                }
+                break;
+            }
+            case 0x0a674065u:
+            {
+                if (name.beginsWith(BuiltInName::clamp))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_clamp_3D3D3D;
+                }
+                break;
+            }
+            case 0x0e503084u:
+            {
+                if (name.beginsWith(BuiltInName::inverse))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_inverse_5B;
+                }
+                break;
+            }
+            case 0x0e507cbdu:
+            {
+                if (name.beginsWith(BuiltInName::inverse))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_inverse_AB;
+                }
+                break;
+            }
+            case 0x0e50cc43u:
+            {
+                if (name.beginsWith(BuiltInName::inverse))
+                {
+                    ASSERT(name.length() == 10);
+                    return &BuiltInFunction::kFunction_inverse_FB;
+                }
+                break;
+            }
+            case 0x0e60445cu:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0S2B;
+                }
+                break;
+            }
+            case 0x0e61222eu:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0K2B;
+                }
+                break;
+            }
+            case 0x0e61df23u:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0V2B;
+                }
+                break;
+            }
+            case 0x0e61e49du:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0Z2B;
+                }
+                break;
+            }
+            case 0x0e625169u:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0I2B;
+                }
+                break;
+            }
+            case 0x0e638fabu:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0Q2B;
+                }
+                break;
+            }
+            case 0x0e63b9efu:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0M1B;
+                }
+                break;
+            }
+            case 0x0e644545u:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0b3B;
+                }
+                break;
+            }
+            case 0x0e646500u:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0W2B;
+                }
+                break;
+            }
+            case 0x0e6470f1u:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0J2B;
+                }
+                break;
+            }
+            case 0x0e64854cu:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0X2B;
+                }
+                break;
+            }
+            case 0x0e65ea73u:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0H1B;
+                }
+                break;
+            }
+            case 0x0e660d38u:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0a3B;
+                }
+                break;
+            }
+            case 0x0e661665u:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0L1B;
+                }
+                break;
+            }
+            case 0x0e663be3u:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0N1B;
+                }
+                break;
+            }
+            case 0x0e66cb64u:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0U1B;
+                }
+                break;
+            }
+            case 0x0e673fffu:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0P1B;
+                }
+                break;
+            }
+            case 0x0e67a979u:
+            {
+                if (name.beginsWith(BuiltInName::texture))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_texture_0R2B;
+                }
+                break;
+            }
+            case 0x106843efu:
+            {
+                if (name.beginsWith(BuiltInName::lessThan))
+                {
+                    ASSERT(name.length() == 13);
+                    return &BuiltInFunction::kFunction_lessThan_3D3D;
+                }
+                break;
+            }
+            case 0x10697de8u:
+            {
+                if (name.beginsWith(BuiltInName::lessThan))
+                {
+                    ASSERT(name.length() == 13);
+                    return &BuiltInFunction::kFunction_lessThan_2D2D;
+                }
+                break;
+            }
+            case 0x106ad530u:
+            {
+                if (name.beginsWith(BuiltInName::notEqual))
+                {
+                    ASSERT(name.length() == 13);
+                    return &BuiltInFunction::kFunction_notEqual_1D1D;
+                }
+                break;
+            }
+            case 0x106d7bd6u:
+            {
+                if (name.beginsWith(BuiltInName::lessThan))
+                {
+                    ASSERT(name.length() == 13);
+                    return &BuiltInFunction::kFunction_lessThan_1D1D;
+                }
+                break;
+            }
+            case 0x106e2903u:
+            {
+                if (name.beginsWith(BuiltInName::notEqual))
+                {
+                    ASSERT(name.length() == 13);
+                    return &BuiltInFunction::kFunction_notEqual_3D3D;
+                }
+                break;
+            }
+            case 0x106e7a45u:
+            {
+                if (name.beginsWith(BuiltInName::notEqual))
+                {
+                    ASSERT(name.length() == 13);
+                    return &BuiltInFunction::kFunction_notEqual_2D2D;
+                }
+                break;
+            }
+            case 0x12601c9du:
+            {
+                if (name.beginsWith(BuiltInName::roundEven))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_roundEven_3B;
+                }
+                break;
+            }
+            case 0x12602fd7u:
+            {
+                if (name.beginsWith(BuiltInName::transpose))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_transpose_AB;
+                }
+                break;
+            }
+            case 0x12614fd4u:
+            {
+                if (name.beginsWith(BuiltInName::roundEven))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_roundEven_2B;
+                }
+                break;
+            }
+            case 0x1264f5e4u:
+            {
+                if (name.beginsWith(BuiltInName::transpose))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_transpose_EB;
+                }
+                break;
+            }
+            case 0x12650771u:
+            {
+                if (name.beginsWith(BuiltInName::transpose))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_transpose_6B;
+                }
+                break;
+            }
+            case 0x12655b22u:
+            {
+                if (name.beginsWith(BuiltInName::transpose))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_transpose_BB;
+                }
+                break;
+            }
+            case 0x12658f24u:
+            {
+                if (name.beginsWith(BuiltInName::transpose))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_transpose_9B;
+                }
+                break;
+            }
+            case 0x1265cf4cu:
+            {
+                if (name.beginsWith(BuiltInName::roundEven))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_roundEven_1B;
+                }
+                break;
+            }
+            case 0x12661b07u:
+            {
+                if (name.beginsWith(BuiltInName::transpose))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_transpose_FB;
+                }
+                break;
+            }
+            case 0x12665430u:
+            {
+                if (name.beginsWith(BuiltInName::transpose))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_transpose_7B;
+                }
+                break;
+            }
+            case 0x1266c2deu:
+            {
+                if (name.beginsWith(BuiltInName::roundEven))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_roundEven_0B;
+                }
+                break;
+            }
+            case 0x1267db60u:
+            {
+                if (name.beginsWith(BuiltInName::transpose))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_transpose_5B;
+                }
+                break;
+            }
+            case 0x1267de6cu:
+            {
+                if (name.beginsWith(BuiltInName::transpose))
+                {
+                    ASSERT(name.length() == 12);
+                    return &BuiltInFunction::kFunction_transpose_DB;
+                }
+                break;
+            }
+            case 0x1273f9dbu:
+            {
+                if (name.beginsWith(BuiltInName::yuv_2_rgb))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_yuv_2_rgb_2B0G;
+                }
+                break;
+            }
+            case 0x127589a7u:
+            {
+                if (name.beginsWith(BuiltInName::rgb_2_yuv))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_rgb_2_yuv_2B0G;
+                }
+                break;
+            }
+            case 0x14880e11u:
+            {
+                if (name == BuiltInName::texelFetch_0V2C0C)
+                {
+                    return &BuiltInFunction::kFunction_texelFetch_0V2C0C;
+                }
+                break;
+            }
+            case 0x14882ba7u:
+            {
+                if (name.beginsWith(BuiltInName::textureLod))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_textureLod_0X2B0B;
+                }
+                break;
+            }
+            case 0x14888557u:
+            {
+                if (name.beginsWith(BuiltInName::textureLod))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_textureLod_0Q2B0B;
+                }
+                break;
+            }
+            case 0x1488b1e8u:
+            {
+                if (name.beginsWith(BuiltInName::texelFetch))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_texelFetch_0Q2C0C;
+                }
+                break;
+            }
+            case 0x14894128u:
+            {
+                if (name.beginsWith(BuiltInName::texelFetch))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_texelFetch_0P1C0C;
+                }
+                break;
+            }
+            case 0x148999efu:
+            {
+                if (name.beginsWith(BuiltInName::textureLod))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_textureLod_0V2B0B;
+                }
+                break;
+            }
+            case 0x148a14a7u:
+            {
+                if (name.beginsWith(BuiltInName::texelFetch))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_texelFetch_0M1C0C;
+                }
+                break;
+            }
+            case 0x148a2382u:
+            {
+                if (name.beginsWith(BuiltInName::texelFetch))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_texelFetch_0S2C0C;
+                }
+                break;
+            }
+            case 0x148a66beu:
+            {
+                if (name == BuiltInName::textureLod_0S2B0B)
+                {
+                    return &BuiltInFunction::kFunction_textureLod_0S2B0B;
+                }
+                break;
+            }
+            case 0x148b00dbu:
+            {
+                if (name == BuiltInName::textureLod_0J2B0B)
+                {
+                    return &BuiltInFunction::kFunction_textureLod_0J2B0B;
+                }
+                break;
+            }
+            case 0x148b33b6u:
+            {
+                if (name.beginsWith(BuiltInName::textureLod))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_textureLod_0H1B0B;
+                }
+                break;
+            }
+            case 0x148bab65u:
+            {
+                if (name == BuiltInName::texelFetch_0I2C0C)
+                {
+                    return &BuiltInFunction::kFunction_texelFetch_0I2C0C;
+                }
+                break;
+            }
+            case 0x148cccafu:
+            {
+                if (name.beginsWith(BuiltInName::textureLod))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_textureLod_0R2B0B;
+                }
+                break;
+            }
+            case 0x148d0a7bu:
+            {
+                if (name == BuiltInName::texelFetch_0K2C0C)
+                {
+                    return &BuiltInFunction::kFunction_texelFetch_0K2C0C;
+                }
+                break;
+            }
+            case 0x148d335cu:
+            {
+                if (name.beginsWith(BuiltInName::textureLod))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_textureLod_0I2B0B;
+                }
+                break;
+            }
+            case 0x148d3512u:
+            {
+                if (name.beginsWith(BuiltInName::textureLod))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_textureLod_0W2B0B;
+                }
+                break;
+            }
+            case 0x148e100eu:
+            {
+                if (name == BuiltInName::texelFetch_0X2C0C)
+                {
+                    return &BuiltInFunction::kFunction_texelFetch_0X2C0C;
+                }
+                break;
+            }
+            case 0x148ed16fu:
+            {
+                if (name.beginsWith(BuiltInName::texelFetch))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_texelFetch_0U1C0C;
+                }
+                break;
+            }
+            case 0x148ed87fu:
+            {
+                if (name.beginsWith(BuiltInName::textureLod))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_textureLod_0K2B0B;
+                }
+                break;
+            }
+            case 0x148eff58u:
+            {
+                if (name == BuiltInName::texelFetch_0L1C0C)
+                {
+                    return &BuiltInFunction::kFunction_texelFetch_0L1C0C;
+                }
+                break;
+            }
+            case 0x148f7fe8u:
+            {
+                if (name.beginsWith(BuiltInName::textureLod))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_textureLod_0U1B0B;
+                }
+                break;
+            }
+            case 0x148fd5b6u:
+            {
+                if (name == BuiltInName::texelFetch_0H1C0C)
+                {
+                    return &BuiltInFunction::kFunction_texelFetch_0H1C0C;
+                }
+                break;
+            }
+            case 0x148fde6au:
+            {
+                if (name == BuiltInName::textureLod_0P1B0B)
+                {
+                    return &BuiltInFunction::kFunction_textureLod_0P1B0B;
+                }
+                break;
+            }
+            case 0x148fe911u:
+            {
+                if (name == BuiltInName::textureLod_0Z2B0B)
+                {
+                    return &BuiltInFunction::kFunction_textureLod_0Z2B0B;
+                }
+                break;
+            }
+            case 0x1673728cu:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_textureSize_0Y;
+                }
+                break;
+            }
+            case 0x1673936bu:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_textureSize_0T;
+                }
+                break;
+            }
+            case 0x1673f496u:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_textureSize_0O;
+                }
+                break;
+            }
+            case 0x1674ed12u:
+            {
+                if (name.beginsWith(BuiltInName::determinant))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_determinant_FB;
+                }
+                break;
+            }
+            case 0x1676ad75u:
+            {
+                if (name.beginsWith(BuiltInName::determinant))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_determinant_5B;
+                }
+                break;
+            }
+            case 0x167719ccu:
+            {
+                if (name.beginsWith(BuiltInName::determinant))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_determinant_AB;
+                }
+                break;
+            }
+            case 0x168021fbu:
+            {
+                if (name.beginsWith(BuiltInName::textureProj))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureProj_0U3B;
+                }
+                break;
+            }
+            case 0x16803d05u:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureSize_0I0C;
+                }
+                break;
+            }
+            case 0x168046b0u:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureSize_0M0C;
+                }
+                break;
+            }
+            case 0x16807544u:
+            {
+                if (name.beginsWith(BuiltInName::textureProj))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureProj_0P3B;
+                }
+                break;
+            }
+            case 0x1680a979u:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureSize_0U0C;
+                }
+                break;
+            }
+            case 0x16812c54u:
+            {
+                if (name.beginsWith(BuiltInName::greaterThan))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_greaterThan_3D3D;
+                }
+                break;
+            }
+            case 0x168174f7u:
+            {
+                if (name.beginsWith(BuiltInName::greaterThan))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_greaterThan_1D1D;
+                }
+                break;
+            }
+            case 0x168178c7u:
+            {
+                if (name.beginsWith(BuiltInName::textureProj))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureProj_0H2B;
+                }
+                break;
+            }
+            case 0x1681a77du:
+            {
+                if (name.beginsWith(BuiltInName::textureProj))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureProj_0P2B;
+                }
+                break;
+            }
+            case 0x1681d6b4u:
+            {
+                if (name.beginsWith(BuiltInName::greaterThan))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_greaterThan_2D2D;
+                }
+                break;
+            }
+            case 0x1681e38fu:
+            {
+                if (name.beginsWith(BuiltInName::textureProj))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureProj_0V3B;
+                }
+                break;
+            }
+            case 0x1681f153u:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureSize_0J0C;
+                }
+                break;
+            }
+            case 0x168245a4u:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureSize_0S0C;
+                }
+                break;
+            }
+            case 0x168255e2u:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureSize_0V0C;
+                }
+                break;
+            }
+            case 0x16829c77u:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureSize_0b0C;
+                }
+                break;
+            }
+            case 0x1682d0c8u:
+            {
+                if (name.beginsWith(BuiltInName::textureProj))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureProj_0M2B;
+                }
+                break;
+            }
+            case 0x16838d15u:
+            {
+                if (name.beginsWith(BuiltInName::textureProj))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureProj_0L2B;
+                }
+                break;
+            }
+            case 0x1683ecb1u:
+            {
+                if (name.beginsWith(BuiltInName::textureProj))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureProj_0M3B;
+                }
+                break;
+            }
+            case 0x16840064u:
+            {
+                if (name.beginsWith(BuiltInName::textureProj))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureProj_0H3B;
+                }
+                break;
+            }
+            case 0x16842f7du:
+            {
+                if (name.beginsWith(BuiltInName::textureProj))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureProj_0Z3B;
+                }
+                break;
+            }
+            case 0x168434eeu:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureSize_0H0C;
+                }
+                break;
+            }
+            case 0x16845c90u:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureSize_0L0C;
+                }
+                break;
+            }
+            case 0x16846c6cu:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureSize_0W0C;
+                }
+                break;
+            }
+            case 0x16849618u:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureSize_0Z0C;
+                }
+                break;
+            }
+            case 0x1685b785u:
+            {
+                if (name.beginsWith(BuiltInName::textureProj))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureProj_0N3B;
+                }
+                break;
+            }
+            case 0x1685ca01u:
+            {
+                if (name.beginsWith(BuiltInName::textureProj))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureProj_0I3B;
+                }
+                break;
+            }
+            case 0x16860d28u:
+            {
+                if (name.beginsWith(BuiltInName::textureProj))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureProj_0Q3B;
+                }
+                break;
+            }
+            case 0x16861104u:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureSize_0K0C;
+                }
+                break;
+            }
+            case 0x16863c73u:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureSize_0R0C;
+                }
+                break;
+            }
+            case 0x16865716u:
+            {
+                if (name.beginsWith(BuiltInName::textureProj))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureProj_0L3B;
+                }
+                break;
+            }
+            case 0x16866f5du:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureSize_0P0C;
+                }
+                break;
+            }
+            case 0x16869d00u:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureSize_0Q0C;
+                }
+                break;
+            }
+            case 0x1686a82au:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureSize_0X0C;
+                }
+                break;
+            }
+            case 0x1686cb94u:
+            {
+                if (name.beginsWith(BuiltInName::textureProj))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureProj_0N2B;
+                }
+                break;
+            }
+            case 0x1686d6ddu:
+            {
+                if (name.beginsWith(BuiltInName::textureSize))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureSize_0a0C;
+                }
+                break;
+            }
+            case 0x168705d2u:
+            {
+                if (name.beginsWith(BuiltInName::textureProj))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureProj_0U2B;
+                }
+                break;
+            }
+            case 0x16a00e04u:
+            {
+                if (name == BuiltInName::textureGrad_0I2B2B2B)
+                {
+                    return &BuiltInFunction::kFunction_textureGrad_0I2B2B2B;
+                }
+                break;
+            }
+            case 0x16a11436u:
+            {
+                if (name == BuiltInName::textureGrad_0W2B2B2B)
+                {
+                    return &BuiltInFunction::kFunction_textureGrad_0W2B2B2B;
+                }
+                break;
+            }
+            case 0x16a149ecu:
+            {
+                if (name == BuiltInName::textureGrad_0a3B2B2B)
+                {
+                    return &BuiltInFunction::kFunction_textureGrad_0a3B2B2B;
+                }
+                break;
+            }
+            case 0x16a19158u:
+            {
+                if (name == BuiltInName::textureGrad_0Q2B2B2B)
+                {
+                    return &BuiltInFunction::kFunction_textureGrad_0Q2B2B2B;
+                }
+                break;
+            }
+            case 0x16a19c8du:
+            {
+                if (name == BuiltInName::textureGrad_0H1B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_textureGrad_0H1B1B1B;
+                }
+                break;
+            }
+            case 0x16a1ec87u:
+            {
+                if (name == BuiltInName::textureGrad_0J2B2B2B)
+                {
+                    return &BuiltInFunction::kFunction_textureGrad_0J2B2B2B;
+                }
+                break;
+            }
+            case 0x16a22779u:
+            {
+                if (name == BuiltInName::textureGrad_0X2B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_textureGrad_0X2B1B1B;
+                }
+                break;
+            }
+            case 0x16a34692u:
+            {
+                if (name == BuiltInName::textureGrad_0R2B2B2B)
+                {
+                    return &BuiltInFunction::kFunction_textureGrad_0R2B2B2B;
+                }
+                break;
+            }
+            case 0x16a47be7u:
+            {
+                if (name == BuiltInName::textureGrad_0P1B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_textureGrad_0P1B1B1B;
+                }
+                break;
+            }
+            case 0x16a53465u:
+            {
+                if (name == BuiltInName::textureGrad_0b3B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_textureGrad_0b3B1B1B;
+                }
+                break;
+            }
+            case 0x16a57654u:
+            {
+                if (name == BuiltInName::textureGrad_0S2B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_textureGrad_0S2B1B1B;
+                }
+                break;
+            }
+            case 0x16a6a742u:
+            {
+                if (name == BuiltInName::textureGrad_0Z2B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_textureGrad_0Z2B1B1B;
+                }
+                break;
+            }
+            case 0x16a71104u:
+            {
+                if (name == BuiltInName::textureGrad_0K2B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_textureGrad_0K2B1B1B;
+                }
+                break;
+            }
+            case 0x16a735dau:
+            {
+                if (name == BuiltInName::textureGrad_0U1B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_textureGrad_0U1B1B1B;
+                }
+                break;
+            }
+            case 0x16a7e88eu:
+            {
+                if (name == BuiltInName::textureGrad_0V2B2B2B)
+                {
+                    return &BuiltInFunction::kFunction_textureGrad_0V2B2B2B;
+                }
+                break;
+            }
+            case 0x187df788u:
+            {
+                if (name.beginsWith(BuiltInName::packHalf2x16))
+                {
+                    ASSERT(name.length() == 15);
+                    return &BuiltInFunction::kFunction_packHalf2x16_1B;
+                }
+                break;
+            }
+            case 0x18887331u:
+            {
+                if (name.beginsWith(BuiltInName::outerProduct))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_outerProduct_2B3B;
+                }
+                break;
+            }
+            case 0x188880cbu:
+            {
+                if (name.beginsWith(BuiltInName::outerProduct))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_outerProduct_1B1B;
+                }
+                break;
+            }
+            case 0x1888c44du:
+            {
+                if (name.beginsWith(BuiltInName::outerProduct))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_outerProduct_3B2B;
+                }
+                break;
+            }
+            case 0x188916c3u:
+            {
+                if (name.beginsWith(BuiltInName::outerProduct))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_outerProduct_1B2B;
+                }
+                break;
+            }
+            case 0x188a12cau:
+            {
+                if (name.beginsWith(BuiltInName::outerProduct))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_outerProduct_1B3B;
+                }
+                break;
+            }
+            case 0x188db87au:
+            {
+                if (name.beginsWith(BuiltInName::outerProduct))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_outerProduct_2B2B;
+                }
+                break;
+            }
+            case 0x188e0232u:
+            {
+                if (name.beginsWith(BuiltInName::outerProduct))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_outerProduct_3B3B;
+                }
+                break;
+            }
+            case 0x188e2270u:
+            {
+                if (name.beginsWith(BuiltInName::outerProduct))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_outerProduct_2B1B;
+                }
+                break;
+            }
+            case 0x188f8feeu:
+            {
+                if (name.beginsWith(BuiltInName::outerProduct))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_outerProduct_3B1B;
+                }
+                break;
+            }
+            case 0x1a84fa77u:
+            {
+                if (name.beginsWith(BuiltInName::packSnorm2x16))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_packSnorm2x16_1B;
+                }
+                break;
+            }
+            case 0x1a873678u:
+            {
+                if (name.beginsWith(BuiltInName::packUnorm2x16))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_packUnorm2x16_1B;
+                }
+                break;
+            }
+            case 0x1a92589du:
+            {
+                if (name.beginsWith(BuiltInName::lessThanEqual))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_lessThanEqual_2D2D;
+                }
+                break;
+            }
+            case 0x1a95efdcu:
+            {
+                if (name.beginsWith(BuiltInName::lessThanEqual))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_lessThanEqual_1D1D;
+                }
+                break;
+            }
+            case 0x1a96ec62u:
+            {
+                if (name.beginsWith(BuiltInName::lessThanEqual))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_lessThanEqual_3D3D;
+                }
+                break;
+            }
+            case 0x1aa08a7au:
+            {
+                if (name == BuiltInName::textureOffset_0V2B2C)
+                {
+                    return &BuiltInFunction::kFunction_textureOffset_0V2B2C;
+                }
+                break;
+            }
+            case 0x1aa0931au:
+            {
+                if (name == BuiltInName::textureOffset_0P1B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureOffset_0P1B1C;
+                }
+                break;
+            }
+            case 0x1aa11785u:
+            {
+                if (name.beginsWith(BuiltInName::textureOffset))
+                {
+                    ASSERT(name.length() == 20);
+                    return &BuiltInFunction::kFunction_textureOffset_0H1B1C;
+                }
+                break;
+            }
+            case 0x1aa1c620u:
+            {
+                if (name.beginsWith(BuiltInName::textureOffset))
+                {
+                    ASSERT(name.length() == 20);
+                    return &BuiltInFunction::kFunction_textureOffset_0U1B1C;
+                }
+                break;
+            }
+            case 0x1aa2cd54u:
+            {
+                if (name == BuiltInName::textureOffset_0S2B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureOffset_0S2B1C;
+                }
+                break;
+            }
+            case 0x1aa385c2u:
+            {
+                if (name.beginsWith(BuiltInName::textureOffset))
+                {
+                    ASSERT(name.length() == 20);
+                    return &BuiltInFunction::kFunction_textureOffset_0Z2B1C;
+                }
+                break;
+            }
+            case 0x1aa39cdeu:
+            {
+                if (name.beginsWith(BuiltInName::textureOffset))
+                {
+                    ASSERT(name.length() == 20);
+                    return &BuiltInFunction::kFunction_textureOffset_0X2B1C;
+                }
+                break;
+            }
+            case 0x1aa3c02eu:
+            {
+                if (name == BuiltInName::textureOffset_0Q2B2C)
+                {
+                    return &BuiltInFunction::kFunction_textureOffset_0Q2B2C;
+                }
+                break;
+            }
+            case 0x1aa41f4au:
+            {
+                if (name.beginsWith(BuiltInName::textureOffset))
+                {
+                    ASSERT(name.length() == 20);
+                    return &BuiltInFunction::kFunction_textureOffset_0K2B1C;
+                }
+                break;
+            }
+            case 0x1aa64995u:
+            {
+                if (name.beginsWith(BuiltInName::textureOffset))
+                {
+                    ASSERT(name.length() == 20);
+                    return &BuiltInFunction::kFunction_textureOffset_0I2B2C;
+                }
+                break;
+            }
+            case 0x1c887424u:
+            {
+                if (name.beginsWith(BuiltInName::intBitsToFloat))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_intBitsToFloat_2C;
+                }
+                break;
+            }
+            case 0x1c887f5eu:
+            {
+                if (name.beginsWith(BuiltInName::floatBitsToInt))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_floatBitsToInt_2B;
+                }
+                break;
+            }
+            case 0x1c88f18cu:
+            {
+                if (name.beginsWith(BuiltInName::intBitsToFloat))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_intBitsToFloat_1C;
+                }
+                break;
+            }
+            case 0x1c89b11cu:
+            {
+                if (name.beginsWith(BuiltInName::floatBitsToInt))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_floatBitsToInt_1B;
+                }
+                break;
+            }
+            case 0x1c89e261u:
+            {
+                if (name.beginsWith(BuiltInName::intBitsToFloat))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_intBitsToFloat_0C;
+                }
+                break;
+            }
+            case 0x1c8ae0a5u:
+            {
+                if (name.beginsWith(BuiltInName::floatBitsToInt))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_floatBitsToInt_0B;
+                }
+                break;
+            }
+            case 0x1c8b20dau:
+            {
+                if (name.beginsWith(BuiltInName::intBitsToFloat))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_intBitsToFloat_3C;
+                }
+                break;
+            }
+            case 0x1c8dd4e6u:
+            {
+                if (name.beginsWith(BuiltInName::unpackHalf2x16))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_unpackHalf2x16_0D;
+                }
+                break;
+            }
+            case 0x1c8f60afu:
+            {
+                if (name.beginsWith(BuiltInName::floatBitsToInt))
+                {
+                    ASSERT(name.length() == 17);
+                    return &BuiltInFunction::kFunction_floatBitsToInt_3B;
+                }
+                break;
+            }
+            case 0x1c9876e4u:
+            {
+                if (name.beginsWith(BuiltInName::matrixCompMult))
+                {
+                    ASSERT(name.length() == 19);
+                    return &BuiltInFunction::kFunction_matrixCompMult_9B9B;
+                }
+                break;
+            }
+            case 0x1c99affcu:
+            {
+                if (name.beginsWith(BuiltInName::matrixCompMult))
+                {
+                    ASSERT(name.length() == 19);
+                    return &BuiltInFunction::kFunction_matrixCompMult_7B7B;
+                }
+                break;
+            }
+            case 0x1c9c8697u:
+            {
+                if (name.beginsWith(BuiltInName::matrixCompMult))
+                {
+                    ASSERT(name.length() == 19);
+                    return &BuiltInFunction::kFunction_matrixCompMult_6B6B;
+                }
+                break;
+            }
+            case 0x1c9ccd5au:
+            {
+                if (name.beginsWith(BuiltInName::matrixCompMult))
+                {
+                    ASSERT(name.length() == 19);
+                    return &BuiltInFunction::kFunction_matrixCompMult_BBBB;
+                }
+                break;
+            }
+            case 0x1c9ea241u:
+            {
+                if (name.beginsWith(BuiltInName::matrixCompMult))
+                {
+                    ASSERT(name.length() == 19);
+                    return &BuiltInFunction::kFunction_matrixCompMult_DBDB;
+                }
+                break;
+            }
+            case 0x1c9fa571u:
+            {
+                if (name.beginsWith(BuiltInName::matrixCompMult))
+                {
+                    ASSERT(name.length() == 19);
+                    return &BuiltInFunction::kFunction_matrixCompMult_EBEB;
+                }
+                break;
+            }
+            case 0x1ca85d55u:
+            {
+                if (name == BuiltInName::textureProjLod_0Q3B0B)
+                {
+                    return &BuiltInFunction::kFunction_textureProjLod_0Q3B0B;
+                }
+                break;
+            }
+            case 0x1ca8adb6u:
+            {
+                if (name.beginsWith(BuiltInName::textureProjLod))
+                {
+                    ASSERT(name.length() == 21);
+                    return &BuiltInFunction::kFunction_textureProjLod_0P2B0B;
+                }
+                break;
+            }
+            case 0x1ca8c89au:
+            {
+                if (name == BuiltInName::textureProjLod_0H3B0B)
+                {
+                    return &BuiltInFunction::kFunction_textureProjLod_0H3B0B;
+                }
+                break;
+            }
+            case 0x1caa108bu:
+            {
+                if (name.beginsWith(BuiltInName::textureProjLod))
+                {
+                    ASSERT(name.length() == 21);
+                    return &BuiltInFunction::kFunction_textureProjLod_0H2B0B;
+                }
+                break;
+            }
+            case 0x1cab218fu:
+            {
+                if (name.beginsWith(BuiltInName::textureProjLod))
+                {
+                    ASSERT(name.length() == 21);
+                    return &BuiltInFunction::kFunction_textureProjLod_0U3B0B;
+                }
+                break;
+            }
+            case 0x1cabc05fu:
+            {
+                if (name.beginsWith(BuiltInName::textureProjLod))
+                {
+                    ASSERT(name.length() == 21);
+                    return &BuiltInFunction::kFunction_textureProjLod_0U2B0B;
+                }
+                break;
+            }
+            case 0x1cad9ae9u:
+            {
+                if (name == BuiltInName::textureProjLod_0V3B0B)
+                {
+                    return &BuiltInFunction::kFunction_textureProjLod_0V3B0B;
+                }
+                break;
+            }
+            case 0x1cadd758u:
+            {
+                if (name.beginsWith(BuiltInName::textureProjLod))
+                {
+                    ASSERT(name.length() == 21);
+                    return &BuiltInFunction::kFunction_textureProjLod_0P3B0B;
+                }
+                break;
+            }
+            case 0x1caef3bcu:
+            {
+                if (name == BuiltInName::textureProjLod_0Z3B0B)
+                {
+                    return &BuiltInFunction::kFunction_textureProjLod_0Z3B0B;
+                }
+                break;
+            }
+            case 0x1caf96afu:
+            {
+                if (name.beginsWith(BuiltInName::textureProjLod))
+                {
+                    ASSERT(name.length() == 21);
+                    return &BuiltInFunction::kFunction_textureProjLod_0I3B0B;
+                }
+                break;
+            }
+            case 0x1e903284u:
+            {
+                if (name.beginsWith(BuiltInName::floatBitsToUint))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_floatBitsToUint_0B;
+                }
+                break;
+            }
+            case 0x1e92e353u:
+            {
+                if (name.beginsWith(BuiltInName::uintBitsToFloat))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_uintBitsToFloat_3D;
+                }
+                break;
+            }
+            case 0x1e93c13fu:
+            {
+                if (name.beginsWith(BuiltInName::uintBitsToFloat))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_uintBitsToFloat_0D;
+                }
+                break;
+            }
+            case 0x1e95201fu:
+            {
+                if (name.beginsWith(BuiltInName::floatBitsToUint))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_floatBitsToUint_1B;
+                }
+                break;
+            }
+            case 0x1e95511bu:
+            {
+                if (name.beginsWith(BuiltInName::unpackSnorm2x16))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_unpackSnorm2x16_0D;
+                }
+                break;
+            }
+            case 0x1e95582au:
+            {
+                if (name.beginsWith(BuiltInName::uintBitsToFloat))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_uintBitsToFloat_1D;
+                }
+                break;
+            }
+            case 0x1e95b0a7u:
+            {
+                if (name.beginsWith(BuiltInName::uintBitsToFloat))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_uintBitsToFloat_2D;
+                }
+                break;
+            }
+            case 0x1e966adcu:
+            {
+                if (name.beginsWith(BuiltInName::floatBitsToUint))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_floatBitsToUint_2B;
+                }
+                break;
+            }
+            case 0x1e9718ffu:
+            {
+                if (name.beginsWith(BuiltInName::unpackUnorm2x16))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_unpackUnorm2x16_0D;
+                }
+                break;
+            }
+            case 0x1e97a505u:
+            {
+                if (name.beginsWith(BuiltInName::floatBitsToUint))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_floatBitsToUint_3B;
+                }
+                break;
+            }
+            case 0x1ec19613u:
+            {
+                if (name == BuiltInName::textureProjGrad_0V3B2B2B)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGrad_0V3B2B2B;
+                }
+                break;
+            }
+            case 0x1ec1ecc3u:
+            {
+                if (name == BuiltInName::textureProjGrad_0Q3B2B2B)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGrad_0Q3B2B2B;
+                }
+                break;
+            }
+            case 0x1ec323fdu:
+            {
+                if (name == BuiltInName::textureProjGrad_0H3B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGrad_0H3B1B1B;
+                }
+                break;
+            }
+            case 0x1ec374bcu:
+            {
+                if (name == BuiltInName::textureProjGrad_0P2B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGrad_0P2B1B1B;
+                }
+                break;
+            }
+            case 0x1ec3ee61u:
+            {
+                if (name == BuiltInName::textureProjGrad_0I3B2B2B)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGrad_0I3B2B2B;
+                }
+                break;
+            }
+            case 0x1ec4aa1fu:
+            {
+                if (name == BuiltInName::textureProjGrad_0U3B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGrad_0U3B1B1B;
+                }
+                break;
+            }
+            case 0x1ec50275u:
+            {
+                if (name == BuiltInName::textureProjGrad_0P3B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGrad_0P3B1B1B;
+                }
+                break;
+            }
+            case 0x1ec5ab9du:
+            {
+                if (name == BuiltInName::textureProjGrad_0H2B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGrad_0H2B1B1B;
+                }
+                break;
+            }
+            case 0x1ec64714u:
+            {
+                if (name == BuiltInName::textureProjGrad_0Z3B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGrad_0Z3B1B1B;
+                }
+                break;
+            }
+            case 0x1ec71f74u:
+            {
+                if (name == BuiltInName::textureProjGrad_0U2B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGrad_0U2B1B1B;
+                }
+                break;
+            }
+            case 0x20a92dc6u:
+            {
+                if (name.beginsWith(BuiltInName::greaterThanEqual))
+                {
+                    ASSERT(name.length() == 21);
+                    return &BuiltInFunction::kFunction_greaterThanEqual_2D2D;
+                }
+                break;
+            }
+            case 0x20ae96edu:
+            {
+                if (name.beginsWith(BuiltInName::greaterThanEqual))
+                {
+                    ASSERT(name.length() == 21);
+                    return &BuiltInFunction::kFunction_greaterThanEqual_3D3D;
+                }
+                break;
+            }
+            case 0x20aedbacu:
+            {
+                if (name.beginsWith(BuiltInName::greaterThanEqual))
+                {
+                    ASSERT(name.length() == 21);
+                    return &BuiltInFunction::kFunction_greaterThanEqual_1D1D;
+                }
+                break;
+            }
+            case 0x20c863e3u:
+            {
+                if (name == BuiltInName::texelFetchOffset_0X2C0C1C)
+                {
+                    return &BuiltInFunction::kFunction_texelFetchOffset_0X2C0C1C;
+                }
+                break;
+            }
+            case 0x20c8fa96u:
+            {
+                if (name == BuiltInName::texelFetchOffset_0I2C0C2C)
+                {
+                    return &BuiltInFunction::kFunction_texelFetchOffset_0I2C0C2C;
+                }
+                break;
+            }
+            case 0x20c91b7du:
+            {
+                if (name == BuiltInName::texelFetchOffset_0S2C0C1C)
+                {
+                    return &BuiltInFunction::kFunction_texelFetchOffset_0S2C0C1C;
+                }
+                break;
+            }
+            case 0x20c97fcau:
+            {
+                if (name == BuiltInName::textureLodOffset_0X2B0B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureLodOffset_0X2B0B1C;
+                }
+                break;
+            }
+            case 0x20c9c544u:
+            {
+                if (name == BuiltInName::texelFetchOffset_0P1C0C1C)
+                {
+                    return &BuiltInFunction::kFunction_texelFetchOffset_0P1C0C1C;
+                }
+                break;
+            }
+            case 0x20ca4914u:
+            {
+                if (name == BuiltInName::textureLodOffset_0Z2B0B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureLodOffset_0Z2B0B1C;
+                }
+                break;
+            }
+            case 0x20ca735fu:
+            {
+                if (name == BuiltInName::textureLodOffset_0V2B0B2C)
+                {
+                    return &BuiltInFunction::kFunction_textureLodOffset_0V2B0B2C;
+                }
+                break;
+            }
+            case 0x20cac068u:
+            {
+                if (name == BuiltInName::texelFetchOffset_0K2C0C1C)
+                {
+                    return &BuiltInFunction::kFunction_texelFetchOffset_0K2C0C1C;
+                }
+                break;
+            }
+            case 0x20caddbdu:
+            {
+                if (name == BuiltInName::textureLodOffset_0S2B0B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureLodOffset_0S2B0B1C;
+                }
+                break;
+            }
+            case 0x20cb3102u:
+            {
+                if (name == BuiltInName::texelFetchOffset_0H1C0C1C)
+                {
+                    return &BuiltInFunction::kFunction_texelFetchOffset_0H1C0C1C;
+                }
+                break;
+            }
+            case 0x20cbd512u:
+            {
+                if (name == BuiltInName::textureLodOffset_0P1B0B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureLodOffset_0P1B0B1C;
+                }
+                break;
+            }
+            case 0x20cc7638u:
+            {
+                if (name == BuiltInName::texelFetchOffset_0U1C0C1C)
+                {
+                    return &BuiltInFunction::kFunction_texelFetchOffset_0U1C0C1C;
+                }
+                break;
+            }
+            case 0x20cc8384u:
+            {
+                if (name == BuiltInName::textureLodOffset_0Q2B0B2C)
+                {
+                    return &BuiltInFunction::kFunction_textureLodOffset_0Q2B0B2C;
+                }
+                break;
+            }
+            case 0x20cc9477u:
+            {
+                if (name == BuiltInName::textureLodOffset_0H1B0B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureLodOffset_0H1B0B1C;
+                }
+                break;
+            }
+            case 0x20cd0de3u:
+            {
+                if (name == BuiltInName::textureLodOffset_0K2B0B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureLodOffset_0K2B0B1C;
+                }
+                break;
+            }
+            case 0x20cd911au:
+            {
+                if (name == BuiltInName::texelFetchOffset_0Q2C0C2C)
+                {
+                    return &BuiltInFunction::kFunction_texelFetchOffset_0Q2C0C2C;
+                }
+                break;
+            }
+            case 0x20cde748u:
+            {
+                if (name == BuiltInName::textureLodOffset_0I2B0B2C)
+                {
+                    return &BuiltInFunction::kFunction_textureLodOffset_0I2B0B2C;
+                }
+                break;
+            }
+            case 0x20ce3ec5u:
+            {
+                if (name == BuiltInName::texelFetchOffset_0V2C0C2C)
+                {
+                    return &BuiltInFunction::kFunction_texelFetchOffset_0V2C0C2C;
+                }
+                break;
+            }
+            case 0x20cfb2d5u:
+            {
+                if (name == BuiltInName::textureLodOffset_0U1B0B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureLodOffset_0U1B0B1C;
+                }
+                break;
+            }
+            case 0x22c0015bu:
+            {
+                if (name.beginsWith(BuiltInName::textureProjOffset))
+                {
+                    ASSERT(name.length() == 24);
+                    return &BuiltInFunction::kFunction_textureProjOffset_0U3B1C;
+                }
+                break;
+            }
+            case 0x22c02df1u:
+            {
+                if (name == BuiltInName::textureProjOffset_0U2B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjOffset_0U2B1C;
+                }
+                break;
+            }
+            case 0x22c0a359u:
+            {
+                if (name == BuiltInName::textureProjOffset_0H2B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjOffset_0H2B1C;
+                }
+                break;
+            }
+            case 0x22c2da46u:
+            {
+                if (name == BuiltInName::textureProjOffset_0H3B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjOffset_0H3B1C;
+                }
+                break;
+            }
+            case 0x22c2db53u:
+            {
+                if (name == BuiltInName::textureProjOffset_0Q3B2C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjOffset_0Q3B2C;
+                }
+                break;
+            }
+            case 0x22c458dcu:
+            {
+                if (name.beginsWith(BuiltInName::textureProjOffset))
+                {
+                    ASSERT(name.length() == 24);
+                    return &BuiltInFunction::kFunction_textureProjOffset_0I3B2C;
+                }
+                break;
+            }
+            case 0x22c4cdaau:
+            {
+                if (name.beginsWith(BuiltInName::textureProjOffset))
+                {
+                    ASSERT(name.length() == 24);
+                    return &BuiltInFunction::kFunction_textureProjOffset_0P2B1C;
+                }
+                break;
+            }
+            case 0x22c528fau:
+            {
+                if (name == BuiltInName::textureProjOffset_0V3B2C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjOffset_0V3B2C;
+                }
+                break;
+            }
+            case 0x22c5ec11u:
+            {
+                if (name.beginsWith(BuiltInName::textureProjOffset))
+                {
+                    ASSERT(name.length() == 24);
+                    return &BuiltInFunction::kFunction_textureProjOffset_0Z3B1C;
+                }
+                break;
+            }
+            case 0x22c6f82eu:
+            {
+                if (name.beginsWith(BuiltInName::textureProjOffset))
+                {
+                    ASSERT(name.length() == 24);
+                    return &BuiltInFunction::kFunction_textureProjOffset_0P3B1C;
+                }
+                break;
+            }
+            case 0x22e059fdu:
+            {
+                if (name == BuiltInName::textureGradOffset_0U1B1B1B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureGradOffset_0U1B1B1B1C;
+                }
+                break;
+            }
+            case 0x22e165b8u:
+            {
+                if (name == BuiltInName::textureGradOffset_0K2B1B1B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureGradOffset_0K2B1B1B1C;
+                }
+                break;
+            }
+            case 0x22e23b04u:
+            {
+                if (name == BuiltInName::textureGradOffset_0X2B1B1B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureGradOffset_0X2B1B1B1C;
+                }
+                break;
+            }
+            case 0x22e2defdu:
+            {
+                if (name == BuiltInName::textureGradOffset_0b3B1B1B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureGradOffset_0b3B1B1B1C;
+                }
+                break;
+            }
+            case 0x22e3e9eau:
+            {
+                if (name == BuiltInName::textureGradOffset_0I2B2B2B2C)
+                {
+                    return &BuiltInFunction::kFunction_textureGradOffset_0I2B2B2B2C;
+                }
+                break;
+            }
+            case 0x22e54911u:
+            {
+                if (name == BuiltInName::textureGradOffset_0S2B1B1B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureGradOffset_0S2B1B1B1C;
+                }
+                break;
+            }
+            case 0x22e57332u:
+            {
+                if (name == BuiltInName::textureGradOffset_0Q2B2B2B2C)
+                {
+                    return &BuiltInFunction::kFunction_textureGradOffset_0Q2B2B2B2C;
+                }
+                break;
+            }
+            case 0x22e62421u:
+            {
+                if (name == BuiltInName::textureGradOffset_0V2B2B2B2C)
+                {
+                    return &BuiltInFunction::kFunction_textureGradOffset_0V2B2B2B2C;
+                }
+                break;
+            }
+            case 0x22e68293u:
+            {
+                if (name == BuiltInName::textureGradOffset_0Z2B1B1B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureGradOffset_0Z2B1B1B1C;
+                }
+                break;
+            }
+            case 0x22e71012u:
+            {
+                if (name == BuiltInName::textureGradOffset_0H1B1B1B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureGradOffset_0H1B1B1B1C;
+                }
+                break;
+            }
+            case 0x22e735f5u:
+            {
+                if (name == BuiltInName::textureGradOffset_0P1B1B1B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureGradOffset_0P1B1B1B1C;
+                }
+                break;
+            }
+            case 0x28e8c0c1u:
+            {
+                if (name == BuiltInName::textureProjLodOffset_0Z3B0B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjLodOffset_0Z3B0B1C;
+                }
+                break;
+            }
+            case 0x28eab462u:
+            {
+                if (name == BuiltInName::textureProjLodOffset_0H2B0B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjLodOffset_0H2B0B1C;
+                }
+                break;
+            }
+            case 0x28eaec64u:
+            {
+                if (name == BuiltInName::textureProjLodOffset_0Q3B0B2C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjLodOffset_0Q3B0B2C;
+                }
+                break;
+            }
+            case 0x28eb831cu:
+            {
+                if (name == BuiltInName::textureProjLodOffset_0V3B0B2C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjLodOffset_0V3B0B2C;
+                }
+                break;
+            }
+            case 0x28eb8605u:
+            {
+                if (name == BuiltInName::textureProjLodOffset_0I3B0B2C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjLodOffset_0I3B0B2C;
+                }
+                break;
+            }
+            case 0x28ebf99eu:
+            {
+                if (name == BuiltInName::textureProjLodOffset_0H3B0B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjLodOffset_0H3B0B1C;
+                }
+                break;
+            }
+            case 0x28ed5e33u:
+            {
+                if (name == BuiltInName::textureProjLodOffset_0P3B0B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjLodOffset_0P3B0B1C;
+                }
+                break;
+            }
+            case 0x28eeff16u:
+            {
+                if (name == BuiltInName::textureProjLodOffset_0P2B0B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjLodOffset_0P2B0B1C;
+                }
+                break;
+            }
+            case 0x28ef67d8u:
+            {
+                if (name == BuiltInName::textureProjLodOffset_0U2B0B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjLodOffset_0U2B0B1C;
+                }
+                break;
+            }
+            case 0x28efc97eu:
+            {
+                if (name == BuiltInName::textureProjLodOffset_0U3B0B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjLodOffset_0U3B0B1C;
+                }
+                break;
+            }
+            case 0x2b00a086u:
+            {
+                if (name == BuiltInName::textureProjGradOffset_0U3B1B1B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGradOffset_0U3B1B1B1C;
+                }
+                break;
+            }
+            case 0x2b00d555u:
+            {
+                if (name == BuiltInName::textureProjGradOffset_0V3B2B2B2C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGradOffset_0V3B2B2B2C;
+                }
+                break;
+            }
+            case 0x2b022418u:
+            {
+                if (name == BuiltInName::textureProjGradOffset_0H3B1B1B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGradOffset_0H3B1B1B1C;
+                }
+                break;
+            }
+            case 0x2b02308fu:
+            {
+                if (name == BuiltInName::textureProjGradOffset_0P2B1B1B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGradOffset_0P2B1B1B1C;
+                }
+                break;
+            }
+            case 0x2b02af8fu:
+            {
+                if (name == BuiltInName::textureProjGradOffset_0I3B2B2B2C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGradOffset_0I3B2B2B2C;
+                }
+                break;
+            }
+            case 0x2b045d17u:
+            {
+                if (name == BuiltInName::textureProjGradOffset_0Q3B2B2B2C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGradOffset_0Q3B2B2B2C;
+                }
+                break;
+            }
+            case 0x2b0472aau:
+            {
+                if (name == BuiltInName::textureProjGradOffset_0Z3B1B1B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGradOffset_0Z3B1B1B1C;
+                }
+                break;
+            }
+            case 0x2b04ab94u:
+            {
+                if (name == BuiltInName::textureProjGradOffset_0U2B1B1B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGradOffset_0U2B1B1B1C;
+                }
+                break;
+            }
+            case 0x2b06523eu:
+            {
+                if (name == BuiltInName::textureProjGradOffset_0P3B1B1B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGradOffset_0P3B1B1B1C;
+                }
+                break;
+            }
+            case 0x2b077535u:
+            {
+                if (name == BuiltInName::textureProjGradOffset_0H2B1B1B1C)
+                {
+                    return &BuiltInFunction::kFunction_textureProjGradOffset_0H2B1B1B1C;
+                }
+                break;
+            }
+            case 0x7ec10648u:
+            {
+                if (name == BuiltInName::gl_MaxProgramTexelOffset)
+                {
+                    return mVar_gl_MaxProgramTexelOffset;
+                }
+                break;
+            }
+            case 0x7ec3c4d1u:
+            {
+                if (name == BuiltInName::gl_MinProgramTexelOffset)
+                {
+                    return mVar_gl_MinProgramTexelOffset;
+                }
+                break;
+            }
+            case 0x7ec8d677u:
+            {
+                if (name == BuiltInName::gl_MaxVertexOutputVectors)
+                {
+                    return mVar_gl_MaxVertexOutputVectors;
+                }
+                break;
+            }
+            case 0x7ed1aaebu:
+            {
+                if (name == BuiltInName::gl_MaxFragmentInputVectors)
+                {
+                    return mVar_gl_MaxFragmentInputVectors;
+                }
+                break;
+            }
+        }
+        if (mShaderType == GL_FRAGMENT_SHADER)
+        {
+            switch (nameHash)
+            {
+                case 0x08394c88u:
+                {
+                    if (name.beginsWith(BuiltInName::dFdy))
+                    {
+                        ASSERT(name.length() == 7);
+                        return &BuiltInFunction::kFunction_dFdy_0B;
+                    }
+                    break;
+                }
+                case 0x08398819u:
+                {
+                    if (name.beginsWith(BuiltInName::dFdx))
+                    {
+                        ASSERT(name.length() == 7);
+                        return &BuiltInFunction::kFunction_dFdx_0B;
+                    }
+                    break;
+                }
+                case 0x083a7081u:
+                {
+                    if (name.beginsWith(BuiltInName::dFdy))
+                    {
+                        ASSERT(name.length() == 7);
+                        return &BuiltInFunction::kFunction_dFdy_1B;
+                    }
+                    break;
+                }
+                case 0x083abe52u:
+                {
+                    if (name.beginsWith(BuiltInName::dFdx))
+                    {
+                        ASSERT(name.length() == 7);
+                        return &BuiltInFunction::kFunction_dFdx_3B;
+                    }
+                    break;
+                }
+                case 0x083b9d7au:
+                {
+                    if (name.beginsWith(BuiltInName::dFdy))
+                    {
+                        ASSERT(name.length() == 7);
+                        return &BuiltInFunction::kFunction_dFdy_2B;
+                    }
+                    break;
+                }
+                case 0x083c0d13u:
+                {
+                    if (name.beginsWith(BuiltInName::dFdx))
+                    {
+                        ASSERT(name.length() == 7);
+                        return &BuiltInFunction::kFunction_dFdx_2B;
+                    }
+                    break;
+                }
+                case 0x083c6796u:
+                {
+                    if (name.beginsWith(BuiltInName::dFdx))
+                    {
+                        ASSERT(name.length() == 7);
+                        return &BuiltInFunction::kFunction_dFdx_1B;
+                    }
+                    break;
+                }
+                case 0x083ced8bu:
+                {
+                    if (name.beginsWith(BuiltInName::dFdy))
+                    {
+                        ASSERT(name.length() == 7);
+                        return &BuiltInFunction::kFunction_dFdy_3B;
+                    }
+                    break;
+                }
+                case 0x0c483e39u:
+                {
+                    if (name.beginsWith(BuiltInName::fwidth))
+                    {
+                        ASSERT(name.length() == 9);
+                        return &BuiltInFunction::kFunction_fwidth_1B;
+                    }
+                    break;
+                }
+                case 0x0c4d354eu:
+                {
+                    if (name.beginsWith(BuiltInName::fwidth))
+                    {
+                        ASSERT(name.length() == 9);
+                        return &BuiltInFunction::kFunction_fwidth_0B;
+                    }
+                    break;
+                }
+                case 0x0c4e7b0cu:
+                {
+                    if (name.beginsWith(BuiltInName::fwidth))
+                    {
+                        ASSERT(name.length() == 9);
+                        return &BuiltInFunction::kFunction_fwidth_3B;
+                    }
+                    break;
+                }
+                case 0x0c4fa8b5u:
+                {
+                    if (name.beginsWith(BuiltInName::fwidth))
+                    {
+                        ASSERT(name.length() == 9);
+                        return &BuiltInFunction::kFunction_fwidth_2B;
+                    }
+                    break;
+                }
+                case 0x0e70395au:
+                {
+                    if (name.beginsWith(BuiltInName::texture))
+                    {
+                        ASSERT(name.length() == 14);
+                        return &BuiltInFunction::kFunction_texture_0U1B0B;
+                    }
+                    break;
+                }
+                case 0x0e70eff9u:
+                {
+                    if (name.beginsWith(BuiltInName::texture))
+                    {
+                        ASSERT(name.length() == 14);
+                        return &BuiltInFunction::kFunction_texture_0X2B0B;
+                    }
+                    break;
+                }
+                case 0x0e71856cu:
+                {
+                    if (name.beginsWith(BuiltInName::texture))
+                    {
+                        ASSERT(name.length() == 14);
+                        return &BuiltInFunction::kFunction_texture_0M1B0B;
+                    }
+                    break;
+                }
+                case 0x0e71dca8u:
+                {
+                    if (name.beginsWith(BuiltInName::texture))
+                    {
+                        ASSERT(name.length() == 14);
+                        return &BuiltInFunction::kFunction_texture_0P1B0B;
+                    }
+                    break;
+                }
+                case 0x0e720b77u:
+                {
+                    if (name == BuiltInName::texture_0V2B0B)
+                    {
+                        return &BuiltInFunction::kFunction_texture_0V2B0B;
+                    }
+                    break;
+                }
+                case 0x0e723219u:
+                {
+                    if (name.beginsWith(BuiltInName::texture))
+                    {
+                        ASSERT(name.length() == 14);
+                        return &BuiltInFunction::kFunction_texture_0L1B0B;
+                    }
+                    break;
+                }
+                case 0x0e734ff8u:
+                {
+                    if (name.beginsWith(BuiltInName::texture))
+                    {
+                        ASSERT(name.length() == 14);
+                        return &BuiltInFunction::kFunction_texture_0Z2B0B;
+                    }
+                    break;
+                }
+                case 0x0e737f67u:
+                {
+                    if (name.beginsWith(BuiltInName::texture))
+                    {
+                        ASSERT(name.length() == 14);
+                        return &BuiltInFunction::kFunction_texture_0Q2B0B;
+                    }
+                    break;
+                }
+                case 0x0e73f4c3u:
+                {
+                    if (name == BuiltInName::texture_0W2B0B)
+                    {
+                        return &BuiltInFunction::kFunction_texture_0W2B0B;
+                    }
+                    break;
+                }
+                case 0x0e742a66u:
+                {
+                    if (name.beginsWith(BuiltInName::texture))
+                    {
+                        ASSERT(name.length() == 14);
+                        return &BuiltInFunction::kFunction_texture_0K2B0B;
+                    }
+                    break;
+                }
+                case 0x0e75399eu:
+                {
+                    if (name.beginsWith(BuiltInName::texture))
+                    {
+                        ASSERT(name.length() == 14);
+                        return &BuiltInFunction::kFunction_texture_0S2B0B;
+                    }
+                    break;
+                }
+                case 0x0e75d15fu:
+                {
+                    if (name.beginsWith(BuiltInName::texture))
+                    {
+                        ASSERT(name.length() == 14);
+                        return &BuiltInFunction::kFunction_texture_0J2B0B;
+                    }
+                    break;
+                }
+                case 0x0e76e7c1u:
+                {
+                    if (name.beginsWith(BuiltInName::texture))
+                    {
+                        ASSERT(name.length() == 14);
+                        return &BuiltInFunction::kFunction_texture_0H1B0B;
+                    }
+                    break;
+                }
+                case 0x0e7720c0u:
+                {
+                    if (name.beginsWith(BuiltInName::texture))
+                    {
+                        ASSERT(name.length() == 14);
+                        return &BuiltInFunction::kFunction_texture_0R2B0B;
+                    }
+                    break;
+                }
+                case 0x0e77a0f1u:
+                {
+                    if (name.beginsWith(BuiltInName::texture))
+                    {
+                        ASSERT(name.length() == 14);
+                        return &BuiltInFunction::kFunction_texture_0a3B0B;
+                    }
+                    break;
+                }
+                case 0x0e77d1c8u:
+                {
+                    if (name.beginsWith(BuiltInName::texture))
+                    {
+                        ASSERT(name.length() == 14);
+                        return &BuiltInFunction::kFunction_texture_0I2B0B;
+                    }
+                    break;
+                }
+                case 0x16900558u:
+                {
+                    if (name.beginsWith(BuiltInName::textureProj))
+                    {
+                        ASSERT(name.length() == 18);
+                        return &BuiltInFunction::kFunction_textureProj_0L3B0B;
+                    }
+                    break;
+                }
+                case 0x1690ae9fu:
+                {
+                    if (name.beginsWith(BuiltInName::textureProj))
+                    {
+                        ASSERT(name.length() == 18);
+                        return &BuiltInFunction::kFunction_textureProj_0M3B0B;
+                    }
+                    break;
+                }
+                case 0x16910ba7u:
+                {
+                    if (name.beginsWith(BuiltInName::textureProj))
+                    {
+                        ASSERT(name.length() == 18);
+                        return &BuiltInFunction::kFunction_textureProj_0Z3B0B;
+                    }
+                    break;
+                }
+                case 0x16911478u:
+                {
+                    if (name.beginsWith(BuiltInName::textureProj))
+                    {
+                        ASSERT(name.length() == 18);
+                        return &BuiltInFunction::kFunction_textureProj_0P3B0B;
+                    }
+                    break;
+                }
+                case 0x1691c2edu:
+                {
+                    if (name.beginsWith(BuiltInName::textureProj))
+                    {
+                        ASSERT(name.length() == 18);
+                        return &BuiltInFunction::kFunction_textureProj_0M2B0B;
+                    }
+                    break;
+                }
+                case 0x1691d656u:
+                {
+                    if (name.beginsWith(BuiltInName::textureProj))
+                    {
+                        ASSERT(name.length() == 18);
+                        return &BuiltInFunction::kFunction_textureProj_0U2B0B;
+                    }
+                    break;
+                }
+                case 0x16925badu:
+                {
+                    if (name.beginsWith(BuiltInName::textureProj))
+                    {
+                        ASSERT(name.length() == 18);
+                        return &BuiltInFunction::kFunction_textureProj_0Q3B0B;
+                    }
+                    break;
+                }
+                case 0x169292f8u:
+                {
+                    if (name.beginsWith(BuiltInName::textureProj))
+                    {
+                        ASSERT(name.length() == 18);
+                        return &BuiltInFunction::kFunction_textureProj_0U3B0B;
+                    }
+                    break;
+                }
+                case 0x169350d8u:
+                {
+                    if (name.beginsWith(BuiltInName::textureProj))
+                    {
+                        ASSERT(name.length() == 18);
+                        return &BuiltInFunction::kFunction_textureProj_0I3B0B;
+                    }
+                    break;
+                }
+                case 0x1695499au:
+                {
+                    if (name.beginsWith(BuiltInName::textureProj))
+                    {
+                        ASSERT(name.length() == 18);
+                        return &BuiltInFunction::kFunction_textureProj_0V3B0B;
+                    }
+                    break;
+                }
+                case 0x16955fbdu:
+                {
+                    if (name.beginsWith(BuiltInName::textureProj))
+                    {
+                        ASSERT(name.length() == 18);
+                        return &BuiltInFunction::kFunction_textureProj_0P2B0B;
+                    }
+                    break;
+                }
+                case 0x16965fd9u:
+                {
+                    if (name.beginsWith(BuiltInName::textureProj))
+                    {
+                        ASSERT(name.length() == 18);
+                        return &BuiltInFunction::kFunction_textureProj_0H3B0B;
+                    }
+                    break;
+                }
+                case 0x1696f029u:
+                {
+                    if (name.beginsWith(BuiltInName::textureProj))
+                    {
+                        ASSERT(name.length() == 18);
+                        return &BuiltInFunction::kFunction_textureProj_0H2B0B;
+                    }
+                    break;
+                }
+                case 0x1697e9b9u:
+                {
+                    if (name.beginsWith(BuiltInName::textureProj))
+                    {
+                        ASSERT(name.length() == 18);
+                        return &BuiltInFunction::kFunction_textureProj_0L2B0B;
+                    }
+                    break;
+                }
+                case 0x1ab09555u:
+                {
+                    if (name == BuiltInName::textureOffset_0Q2B2C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureOffset_0Q2B2C0B;
+                    }
+                    break;
+                }
+                case 0x1ab0d39du:
+                {
+                    if (name == BuiltInName::textureOffset_0V2B2C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureOffset_0V2B2C0B;
+                    }
+                    break;
+                }
+                case 0x1ab1990bu:
+                {
+                    if (name == BuiltInName::textureOffset_0X2B1C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureOffset_0X2B1C0B;
+                    }
+                    break;
+                }
+                case 0x1ab29724u:
+                {
+                    if (name == BuiltInName::textureOffset_0Z2B1C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureOffset_0Z2B1C0B;
+                    }
+                    break;
+                }
+                case 0x1ab2a609u:
+                {
+                    if (name == BuiltInName::textureOffset_0U1B1C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureOffset_0U1B1C0B;
+                    }
+                    break;
+                }
+                case 0x1ab57bbcu:
+                {
+                    if (name == BuiltInName::textureOffset_0H1B1C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureOffset_0H1B1C0B;
+                    }
+                    break;
+                }
+                case 0x1ab59b6cu:
+                {
+                    if (name == BuiltInName::textureOffset_0I2B2C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureOffset_0I2B2C0B;
+                    }
+                    break;
+                }
+                case 0x1ab63ddau:
+                {
+                    if (name == BuiltInName::textureOffset_0K2B1C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureOffset_0K2B1C0B;
+                    }
+                    break;
+                }
+                case 0x1ab6ec2cu:
+                {
+                    if (name == BuiltInName::textureOffset_0P1B1C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureOffset_0P1B1C0B;
+                    }
+                    break;
+                }
+                case 0x1ab6f64bu:
+                {
+                    if (name == BuiltInName::textureOffset_0S2B1C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureOffset_0S2B1C0B;
+                    }
+                    break;
+                }
+                case 0x22d09aefu:
+                {
+                    if (name == BuiltInName::textureProjOffset_0V3B2C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureProjOffset_0V3B2C0B;
+                    }
+                    break;
+                }
+                case 0x22d2de73u:
+                {
+                    if (name == BuiltInName::textureProjOffset_0U3B1C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureProjOffset_0U3B1C0B;
+                    }
+                    break;
+                }
+                case 0x22d3c514u:
+                {
+                    if (name == BuiltInName::textureProjOffset_0P3B1C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureProjOffset_0P3B1C0B;
+                    }
+                    break;
+                }
+                case 0x22d3ece3u:
+                {
+                    if (name == BuiltInName::textureProjOffset_0Q3B2C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureProjOffset_0Q3B2C0B;
+                    }
+                    break;
+                }
+                case 0x22d59e0cu:
+                {
+                    if (name == BuiltInName::textureProjOffset_0Z3B1C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureProjOffset_0Z3B1C0B;
+                    }
+                    break;
+                }
+                case 0x22d62e81u:
+                {
+                    if (name == BuiltInName::textureProjOffset_0H3B1C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureProjOffset_0H3B1C0B;
+                    }
+                    break;
+                }
+                case 0x22d65c37u:
+                {
+                    if (name == BuiltInName::textureProjOffset_0U2B1C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureProjOffset_0U2B1C0B;
+                    }
+                    break;
+                }
+                case 0x22d6b2e8u:
+                {
+                    if (name == BuiltInName::textureProjOffset_0I3B2C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureProjOffset_0I3B2C0B;
+                    }
+                    break;
+                }
+                case 0x22d6ee53u:
+                {
+                    if (name == BuiltInName::textureProjOffset_0H2B1C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureProjOffset_0H2B1C0B;
+                    }
+                    break;
+                }
+                case 0x22d76183u:
+                {
+                    if (name == BuiltInName::textureProjOffset_0P2B1C0B)
+                    {
+                        return &BuiltInFunction::kFunction_textureProjOffset_0P2B1C0B;
+                    }
+                    break;
+                }
+                case 0x7e645c89u:
+                {
+                    if (name == BuiltInName::gl_FragDepth)
+                    {
+                        return &BuiltInVariable::kVar_gl_FragDepth;
+                    }
+                    break;
+                }
+            }
+        }
+        if (mShaderType == GL_VERTEX_SHADER)
+        {
+            switch (nameHash)
+            {
+                case 0x7e5f8987u:
+                {
+                    if (name == BuiltInName::gl_VertexID)
+                    {
+                        return &BuiltInVariable::kVar_gl_VertexID;
+                    }
+                    break;
+                }
+                case 0x7e6be47fu:
+                {
+                    if (name == BuiltInName::gl_InstanceID)
+                    {
+                        return &BuiltInVariable::kVar_gl_InstanceID;
+                    }
+                    break;
+                }
+            }
+        }
+        if (mResources.OVR_multiview && mShaderType != GL_COMPUTE_SHADER)
+        {
+            switch (nameHash)
+            {
+                case 0x7e6f6de9u:
+                {
+                    if (name == BuiltInName::gl_ViewID_OVR)
+                    {
+                        return &BuiltInVariable::kVar_gl_ViewID_OVR;
+                    }
+                    break;
+                }
+            }
+        }
+    }
+    if (shaderVersion == 100)
+    {
+        switch (nameHash)
+        {
+            case 0x1271689cu:
+            {
+                if (name.beginsWith(BuiltInName::texture2D))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_texture2D_0H1B;
+                }
+                break;
+            }
+            case 0x127728cau:
+            {
+                if (name.beginsWith(BuiltInName::texture2D))
+                {
+                    ASSERT(name.length() == 14);
+                    return &BuiltInFunction::kFunction_texture2D_0L1B;
+                }
+                break;
+            }
+            case 0x1680927du:
+            {
+                if (name.beginsWith(BuiltInName::textureCube))
+                {
+                    ASSERT(name.length() == 16);
+                    return &BuiltInFunction::kFunction_textureCube_0J2B;
+                }
+                break;
+            }
+            case 0x1a902408u:
+            {
+                if (name.beginsWith(BuiltInName::texture2DRect))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_texture2DRect_0N1B;
+                }
+                break;
+            }
+            case 0x1a92969du:
+            {
+                if (name.beginsWith(BuiltInName::texture2DProj))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_texture2DProj_0L2B;
+                }
+                break;
+            }
+            case 0x1a9584eau:
+            {
+                if (name.beginsWith(BuiltInName::texture2DProj))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_texture2DProj_0L3B;
+                }
+                break;
+            }
+            case 0x1a95bcc7u:
+            {
+                if (name.beginsWith(BuiltInName::texture2DProj))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_texture2DProj_0H3B;
+                }
+                break;
+            }
+            case 0x1a96b8d6u:
+            {
+                if (name.beginsWith(BuiltInName::texture2DProj))
+                {
+                    ASSERT(name.length() == 18);
+                    return &BuiltInFunction::kFunction_texture2DProj_0H2B;
+                }
+                break;
+            }
+            case 0x20cb8d71u:
+            {
+                if (name == BuiltInName::texture2DGradEXT_0H1B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_texture2DGradEXT_0H1B1B1B;
+                }
+                break;
+            }
+            case 0x22b53a05u:
+            {
+                if (name.beginsWith(BuiltInName::texture2DRectProj))
+                {
+                    ASSERT(name.length() == 22);
+                    return &BuiltInFunction::kFunction_texture2DRectProj_0N3B;
+                }
+                break;
+            }
+            case 0x22b65e05u:
+            {
+                if (name.beginsWith(BuiltInName::texture2DRectProj))
+                {
+                    ASSERT(name.length() == 22);
+                    return &BuiltInFunction::kFunction_texture2DRectProj_0N2B;
+                }
+                break;
+            }
+            case 0x24dbd51eu:
+            {
+                if (name == BuiltInName::textureCubeGradEXT_0J2B2B2B)
+                {
+                    return &BuiltInFunction::kFunction_textureCubeGradEXT_0J2B2B2B;
+                }
+                break;
+            }
+            case 0x28e995cbu:
+            {
+                if (name == BuiltInName::texture2DProjGradEXT_0H3B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_texture2DProjGradEXT_0H3B1B1B;
+                }
+                break;
+            }
+            case 0x28ed5178u:
+            {
+                if (name == BuiltInName::texture2DProjGradEXT_0H2B1B1B)
+                {
+                    return &BuiltInFunction::kFunction_texture2DProjGradEXT_0H2B1B1B;
+                }
+                break;
+            }
+            case 0x7e5a0c08u:
+            {
+                if (name == BuiltInName::gl_FragData)
+                {
+                    // Only initialized if shaderType == GL_FRAGMENT_SHADER
+                    return mVar_gl_FragData;
+                }
+                break;
+            }
+            case 0x7e7c38efu:
+            {
+                if (name == BuiltInName::gl_FragDepthEXT)
+                {
+                    // Only initialized if (shaderType == GL_FRAGMENT_SHADER) &&
+                    // (mResources.EXT_frag_depth)
+                    return mVar_gl_FragDepthEXT;
+                }
+                break;
+            }
+            case 0x7ea6cdf6u:
+            {
+                if (name == BuiltInName::gl_MaxVaryingVectors)
+                {
+                    return mVar_gl_MaxVaryingVectors;
+                }
+                break;
+            }
+            case 0x7ebce486u:
+            {
+                if (name == BuiltInName::gl_SecondaryFragDataEXT)
+                {
+                    // Only initialized if (shaderType == GL_FRAGMENT_SHADER) &&
+                    // (mResources.EXT_blend_func_extended)
+                    return mVar_gl_SecondaryFragDataEXT;
+                }
+                break;
+            }
+        }
+        if (mShaderType == GL_FRAGMENT_SHADER)
+        {
+            switch (nameHash)
+            {
+                case 0x08394c88u:
+                {
+                    if (name.beginsWith(BuiltInName::dFdyExt))
+                    {
+                        ASSERT(name.length() == 7);
+                        return &BuiltInFunction::kFunction_dFdyExt_0B;
+                    }
+                    break;
+                }
+                case 0x08398819u:
+                {
+                    if (name.beginsWith(BuiltInName::dFdxExt))
+                    {
+                        ASSERT(name.length() == 7);
+                        return &BuiltInFunction::kFunction_dFdxExt_0B;
+                    }
+                    break;
+                }
+                case 0x083a7081u:
+                {
+                    if (name.beginsWith(BuiltInName::dFdyExt))
+                    {
+                        ASSERT(name.length() == 7);
+                        return &BuiltInFunction::kFunction_dFdyExt_1B;
+                    }
+                    break;
+                }
+                case 0x083abe52u:
+                {
+                    if (name.beginsWith(BuiltInName::dFdxExt))
+                    {
+                        ASSERT(name.length() == 7);
+                        return &BuiltInFunction::kFunction_dFdxExt_3B;
+                    }
+                    break;
+                }
+                case 0x083b9d7au:
+                {
+                    if (name.beginsWith(BuiltInName::dFdyExt))
+                    {
+                        ASSERT(name.length() == 7);
+                        return &BuiltInFunction::kFunction_dFdyExt_2B;
+                    }
+                    break;
+                }
+                case 0x083c0d13u:
+                {
+                    if (name.beginsWith(BuiltInName::dFdxExt))
+                    {
+                        ASSERT(name.length() == 7);
+                        return &BuiltInFunction::kFunction_dFdxExt_2B;
+                    }
+                    break;
+                }
+                case 0x083c6796u:
+                {
+                    if (name.beginsWith(BuiltInName::dFdxExt))
+                    {
+                        ASSERT(name.length() == 7);
+                        return &BuiltInFunction::kFunction_dFdxExt_1B;
+                    }
+                    break;
+                }
+                case 0x083ced8bu:
+                {
+                    if (name.beginsWith(BuiltInName::dFdyExt))
+                    {
+                        ASSERT(name.length() == 7);
+                        return &BuiltInFunction::kFunction_dFdyExt_3B;
+                    }
+                    break;
+                }
+                case 0x0c483e39u:
+                {
+                    if (name.beginsWith(BuiltInName::fwidthExt))
+                    {
+                        ASSERT(name.length() == 9);
+                        return &BuiltInFunction::kFunction_fwidthExt_1B;
+                    }
+                    break;
+                }
+                case 0x0c4d354eu:
+                {
+                    if (name.beginsWith(BuiltInName::fwidthExt))
+                    {
+                        ASSERT(name.length() == 9);
+                        return &BuiltInFunction::kFunction_fwidthExt_0B;
+                    }
+                    break;
+                }
+                case 0x0c4e7b0cu:
+                {
+                    if (name.beginsWith(BuiltInName::fwidthExt))
+                    {
+                        ASSERT(name.length() == 9);
+                        return &BuiltInFunction::kFunction_fwidthExt_3B;
+                    }
+                    break;
+                }
+                case 0x0c4fa8b5u:
+                {
+                    if (name.beginsWith(BuiltInName::fwidthExt))
+                    {
+                        ASSERT(name.length() == 9);
+                        return &BuiltInFunction::kFunction_fwidthExt_2B;
+                    }
+                    break;
+                }
+                case 0x12846ba6u:
+                {
+                    if (name.beginsWith(BuiltInName::texture2D))
+                    {
+                        ASSERT(name.length() == 16);
+                        return &BuiltInFunction::kFunction_texture2D_0H1B0B;
+                    }
+                    break;
+                }
+                case 0x1696a314u:
+                {
+                    if (name.beginsWith(BuiltInName::textureCube))
+                    {
+                        ASSERT(name.length() == 18);
+                        return &BuiltInFunction::kFunction_textureCube_0J2B0B;
+                    }
+                    break;
+                }
+                case 0x1aa197a7u:
+                {
+                    if (name.beginsWith(BuiltInName::texture2DProj))
+                    {
+                        ASSERT(name.length() == 20);
+                        return &BuiltInFunction::kFunction_texture2DProj_0H3B0B;
+                    }
+                    break;
+                }
+                case 0x1aa44389u:
+                {
+                    if (name == BuiltInName::texture2DProj_0H2B0B)
+                    {
+                        return &BuiltInFunction::kFunction_texture2DProj_0H2B0B;
+                    }
+                    break;
+                }
+                case 0x1eb43b6cu:
+                {
+                    if (name.beginsWith(BuiltInName::texture2DLodEXT))
+                    {
+                        ASSERT(name.length() == 22);
+                        return &BuiltInFunction::kFunction_texture2DLodEXT_0H1B0B;
+                    }
+                    break;
+                }
+                case 0x22c206a5u:
+                {
+                    if (name.beginsWith(BuiltInName::textureCubeLodEXT))
+                    {
+                        ASSERT(name.length() == 24);
+                        return &BuiltInFunction::kFunction_textureCubeLodEXT_0J2B0B;
+                    }
+                    break;
+                }
+                case 0x26d1d3beu:
+                {
+                    if (name.beginsWith(BuiltInName::texture2DProjLodEXT))
+                    {
+                        ASSERT(name.length() == 26);
+                        return &BuiltInFunction::kFunction_texture2DProjLodEXT_0H3B0B;
+                    }
+                    break;
+                }
+                case 0x26d60d82u:
+                {
+                    if (name.beginsWith(BuiltInName::texture2DProjLodEXT))
+                    {
+                        ASSERT(name.length() == 26);
+                        return &BuiltInFunction::kFunction_texture2DProjLodEXT_0H2B0B;
+                    }
+                    break;
+                }
+                case 0x7e60c438u:
+                {
+                    if (name == BuiltInName::gl_FragColor)
+                    {
+                        return &BuiltInVariable::kVar_gl_FragColor;
+                    }
+                    break;
+                }
+            }
+        }
+        if (mShaderType == GL_VERTEX_SHADER)
+        {
+            switch (nameHash)
+            {
+                case 0x18986fc2u:
+                {
+                    if (name.beginsWith(BuiltInName::texture2DLod))
+                    {
+                        ASSERT(name.length() == 19);
+                        return &BuiltInFunction::kFunction_texture2DLod_0H1B0B;
+                    }
+                    break;
+                }
+                case 0x1cac1f4du:
+                {
+                    if (name.beginsWith(BuiltInName::textureCubeLod))
+                    {
+                        ASSERT(name.length() == 21);
+                        return &BuiltInFunction::kFunction_textureCubeLod_0J2B0B;
+                    }
+                    break;
+                }
+                case 0x20b8a0c3u:
+                {
+                    if (name.beginsWith(BuiltInName::texture2DProjLod))
+                    {
+                        ASSERT(name.length() == 23);
+                        return &BuiltInFunction::kFunction_texture2DProjLod_0H3B0B;
+                    }
+                    break;
+                }
+                case 0x20bc6337u:
+                {
+                    if (name == BuiltInName::texture2DProjLod_0H2B0B)
+                    {
+                        return &BuiltInFunction::kFunction_texture2DProjLod_0H2B0B;
+                    }
+                    break;
+                }
+            }
+        }
+        if ((mShaderType == GL_FRAGMENT_SHADER) && (mResources.EXT_blend_func_extended))
+        {
+            switch (nameHash)
+            {
+                case 0x7ec56cbeu:
+                {
+                    if (name == BuiltInName::gl_SecondaryFragColorEXT)
+                    {
+                        return &BuiltInVariable::kVar_gl_SecondaryFragColorEXT;
+                    }
+                    break;
+                }
+            }
+        }
+        if ((mShaderType == GL_FRAGMENT_SHADER) && (mResources.EXT_shader_framebuffer_fetch))
+        {
+            switch (nameHash)
+            {
+                case 0x7e7970c2u:
+                {
+                    if (name == BuiltInName::gl_LastFragData)
+                    {
+                        return mVar_gl_LastFragData;
+                    }
+                    break;
+                }
+            }
+        }
+        if ((mShaderType == GL_FRAGMENT_SHADER) && (mResources.NV_shader_framebuffer_fetch))
+        {
+            switch (nameHash)
+            {
+                case 0x7e7970c2u:
+                {
+                    if (name == BuiltInName::gl_LastFragData)
+                    {
+                        return mVar_gl_LastFragDataNV;
+                    }
+                    break;
+                }
+                case 0x7e802016u:
+                {
+                    if (name == BuiltInName::gl_LastFragColor)
+                    {
+                        return &BuiltInVariable::kVar_gl_LastFragColor;
+                    }
+                    break;
+                }
+            }
+        }
+        if ((mShaderType == GL_FRAGMENT_SHADER) &&
+            (!mResources.EXT_shader_framebuffer_fetch && !mResources.NV_shader_framebuffer_fetch &&
+             mResources.ARM_shader_framebuffer_fetch))
+        {
+            switch (nameHash)
+            {
+                case 0x7e9f0a88u:
+                {
+                    if (name == BuiltInName::gl_LastFragColorARM)
+                    {
+                        return &BuiltInVariable::kVar_gl_LastFragColorARM;
+                    }
+                    break;
+                }
+            }
+        }
+        if (mResources.OVR_multiview && mShaderType != GL_COMPUTE_SHADER)
+        {
+            switch (nameHash)
+            {
+                case 0x7e6f6de9u:
+                {
+                    if (name == BuiltInName::gl_ViewID_OVR)
+                    {
+                        return &BuiltInVariable::kVar_gl_ViewID_OVRESSL1;
+                    }
+                    break;
+                }
+            }
+        }
+    }
+    switch (nameHash)
+    {
+        case 0x063055e6u:
+        {
+            if (name.beginsWith(BuiltInName::log))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_log_0B;
+            }
+            break;
+        }
+        case 0x06307fbcu:
+        {
+            if (name.beginsWith(BuiltInName::all))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_all_1E;
+            }
+            break;
+        }
+        case 0x0630826fu:
+        {
+            if (name.beginsWith(BuiltInName::notFunc))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_notFunc_3E;
+            }
+            break;
+        }
+        case 0x0630942fu:
+        {
+            if (name.beginsWith(BuiltInName::abs))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_abs_0B;
+            }
+            break;
+        }
+        case 0x06309ccau:
+        {
+            if (name.beginsWith(BuiltInName::tan))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_tan_1B;
+            }
+            break;
+        }
+        case 0x0630bc6au:
+        {
+            if (name.beginsWith(BuiltInName::cos))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_cos_2B;
+            }
+            break;
+        }
+        case 0x0630dce3u:
+        {
+            if (name.beginsWith(BuiltInName::log))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_log_3B;
+            }
+            break;
+        }
+        case 0x063194bfu:
+        {
+            if (name.beginsWith(BuiltInName::any))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_any_1E;
+            }
+            break;
+        }
+        case 0x0631a1ccu:
+        {
+            if (name.beginsWith(BuiltInName::abs))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_abs_3B;
+            }
+            break;
+        }
+        case 0x0631d12au:
+        {
+            if (name.beginsWith(BuiltInName::log))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_log_2B;
+            }
+            break;
+        }
+        case 0x06320b8bu:
+        {
+            if (name.beginsWith(BuiltInName::cos))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_cos_3B;
+            }
+            break;
+        }
+        case 0x0632fcb3u:
+        {
+            if (name.beginsWith(BuiltInName::any))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_any_3E;
+            }
+            break;
+        }
+        case 0x06330b41u:
+        {
+            if (name.beginsWith(BuiltInName::log))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_log_1B;
+            }
+            break;
+        }
+        case 0x063314b1u:
+        {
+            if (name.beginsWith(BuiltInName::sin))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_sin_1B;
+            }
+            break;
+        }
+        case 0x063415e2u:
+        {
+            if (name.beginsWith(BuiltInName::any))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_any_2E;
+            }
+            break;
+        }
+        case 0x06344570u:
+        {
+            if (name.beginsWith(BuiltInName::sin))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_sin_0B;
+            }
+            break;
+        }
+        case 0x0634cf9au:
+        {
+            if (name.beginsWith(BuiltInName::sin))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_sin_3B;
+            }
+            break;
+        }
+        case 0x06352335u:
+        {
+            if (name.beginsWith(BuiltInName::exp))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_exp_3B;
+            }
+            break;
+        }
+        case 0x063595b9u:
+        {
+            if (name.beginsWith(BuiltInName::exp))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_exp_0B;
+            }
+            break;
+        }
+        case 0x0635a80fu:
+        {
+            if (name.beginsWith(BuiltInName::tan))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_tan_2B;
+            }
+            break;
+        }
+        case 0x0635d3b3u:
+        {
+            if (name.beginsWith(BuiltInName::sin))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_sin_2B;
+            }
+            break;
+        }
+        case 0x0635eb79u:
+        {
+            if (name.beginsWith(BuiltInName::all))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_all_2E;
+            }
+            break;
+        }
+        case 0x06366a98u:
+        {
+            if (name.beginsWith(BuiltInName::cos))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_cos_0B;
+            }
+            break;
+        }
+        case 0x0636b1f1u:
+        {
+            if (name.beginsWith(BuiltInName::exp))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_exp_1B;
+            }
+            break;
+        }
+        case 0x0636dda0u:
+        {
+            if (name.beginsWith(BuiltInName::all))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_all_3E;
+            }
+            break;
+        }
+        case 0x0636e0efu:
+        {
+            if (name.beginsWith(BuiltInName::notFunc))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_notFunc_1E;
+            }
+            break;
+        }
+        case 0x063719d6u:
+        {
+            if (name.beginsWith(BuiltInName::tan))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_tan_3B;
+            }
+            break;
+        }
+        case 0x06371aefu:
+        {
+            if (name.beginsWith(BuiltInName::abs))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_abs_2B;
+            }
+            break;
+        }
+        case 0x06376a86u:
+        {
+            if (name.beginsWith(BuiltInName::notFunc))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_notFunc_2E;
+            }
+            break;
+        }
+        case 0x063770d0u:
+        {
+            if (name.beginsWith(BuiltInName::tan))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_tan_0B;
+            }
+            break;
+        }
+        case 0x063770dfu:
+        {
+            if (name.beginsWith(BuiltInName::abs))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_abs_1B;
+            }
+            break;
+        }
+        case 0x063786f1u:
+        {
+            if (name.beginsWith(BuiltInName::cos))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_cos_1B;
+            }
+            break;
+        }
+        case 0x0637ca4au:
+        {
+            if (name.beginsWith(BuiltInName::exp))
+            {
+                ASSERT(name.length() == 6);
+                return &BuiltInFunction::kFunction_exp_2B;
+            }
+            break;
+        }
+        case 0x06400261u:
+        {
+            if (name.beginsWith(BuiltInName::max))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_max_2B2B;
+            }
+            break;
+        }
+        case 0x06403847u:
+        {
+            if (name.beginsWith(BuiltInName::mod))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_mod_2B0B;
+            }
+            break;
+        }
+        case 0x064082ceu:
+        {
+            if (name.beginsWith(BuiltInName::mod))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_mod_1B0B;
+            }
+            break;
+        }
+        case 0x0640a98au:
+        {
+            if (name.beginsWith(BuiltInName::min))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_min_2B2B;
+            }
+            break;
+        }
+        case 0x064107b7u:
+        {
+            if (name.beginsWith(BuiltInName::min))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_min_1B0B;
+            }
+            break;
+        }
+        case 0x06415ae6u:
+        {
+            if (name.beginsWith(BuiltInName::dot))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_dot_3B3B;
+            }
+            break;
+        }
+        case 0x06418e42u:
+        {
+            if (name.beginsWith(BuiltInName::pow))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_pow_3B3B;
+            }
+            break;
+        }
+        case 0x0641ceeeu:
+        {
+            if (name.beginsWith(BuiltInName::min))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_min_0B0B;
+            }
+            break;
+        }
+        case 0x0641f1d7u:
+        {
+            if (name.beginsWith(BuiltInName::mod))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_mod_1B1B;
+            }
+            break;
+        }
+        case 0x06421555u:
+        {
+            if (name.beginsWith(BuiltInName::dot))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_dot_1B1B;
+            }
+            break;
+        }
+        case 0x064225ceu:
+        {
+            if (name.beginsWith(BuiltInName::max))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_max_3B3B;
+            }
+            break;
+        }
+        case 0x064274eeu:
+        {
+            if (name.beginsWith(BuiltInName::min))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_min_1B1B;
+            }
+            break;
+        }
+        case 0x0642b54du:
+        {
+            if (name.beginsWith(BuiltInName::mod))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_mod_2B2B;
+            }
+            break;
+        }
+        case 0x064318fcu:
+        {
+            if (name.beginsWith(BuiltInName::pow))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_pow_2B2B;
+            }
+            break;
+        }
+        case 0x0643486cu:
+        {
+            if (name.beginsWith(BuiltInName::max))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_max_3B0B;
+            }
+            break;
+        }
+        case 0x06439435u:
+        {
+            if (name.beginsWith(BuiltInName::pow))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_pow_1B1B;
+            }
+            break;
+        }
+        case 0x06450933u:
+        {
+            if (name.beginsWith(BuiltInName::dot))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_dot_0B0B;
+            }
+            break;
+        }
+        case 0x0645114fu:
+        {
+            if (name.beginsWith(BuiltInName::max))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_max_1B0B;
+            }
+            break;
+        }
+        case 0x06457883u:
+        {
+            if (name.beginsWith(BuiltInName::mod))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_mod_3B3B;
+            }
+            break;
+        }
+        case 0x0645f03eu:
+        {
+            if (name.beginsWith(BuiltInName::mod))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_mod_3B0B;
+            }
+            break;
+        }
+        case 0x0645fd82u:
+        {
+            if (name.beginsWith(BuiltInName::min))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_min_3B3B;
+            }
+            break;
+        }
+        case 0x0646155eu:
+        {
+            if (name.beginsWith(BuiltInName::max))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_max_1B1B;
+            }
+            break;
+        }
+        case 0x06462cf0u:
+        {
+            if (name.beginsWith(BuiltInName::min))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_min_2B0B;
+            }
+            break;
+        }
+        case 0x06463219u:
+        {
+            if (name.beginsWith(BuiltInName::dot))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_dot_2B2B;
+            }
+            break;
+        }
+        case 0x06467507u:
+        {
+            if (name.beginsWith(BuiltInName::min))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_min_3B0B;
+            }
+            break;
+        }
+        case 0x06468fb1u:
+        {
+            if (name.beginsWith(BuiltInName::max))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_max_2B0B;
+            }
+            break;
+        }
+        case 0x0646b392u:
+        {
+            if (name.beginsWith(BuiltInName::pow))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_pow_0B0B;
+            }
+            break;
+        }
+        case 0x06472996u:
+        {
+            if (name.beginsWith(BuiltInName::max))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_max_0B0B;
+            }
+            break;
+        }
+        case 0x064778feu:
+        {
+            if (name.beginsWith(BuiltInName::mod))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_mod_0B0B;
+            }
+            break;
+        }
+        case 0x0650f1c9u:
+        {
+            if (name.beginsWith(BuiltInName::mix))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_mix_1B1B0B;
+            }
+            break;
+        }
+        case 0x0653049du:
+        {
+            if (name.beginsWith(BuiltInName::mix))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_mix_2B2B0B;
+            }
+            break;
+        }
+        case 0x06549219u:
+        {
+            if (name.beginsWith(BuiltInName::mix))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_mix_2B2B2B;
+            }
+            break;
+        }
+        case 0x0655be57u:
+        {
+            if (name.beginsWith(BuiltInName::mix))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_mix_0B0B0B;
+            }
+            break;
+        }
+        case 0x06561bdcu:
+        {
+            if (name == BuiltInName::mix_3B3B0B)
+            {
+                return &BuiltInFunction::kFunction_mix_3B3B0B;
+            }
+            break;
+        }
+        case 0x06568deeu:
+        {
+            if (name == BuiltInName::mix_3B3B3B)
+            {
+                return &BuiltInFunction::kFunction_mix_3B3B3B;
+            }
+            break;
+        }
+        case 0x0657a0a8u:
+        {
+            if (name == BuiltInName::mix_1B1B1B)
+            {
+                return &BuiltInFunction::kFunction_mix_1B1B1B;
+            }
+            break;
+        }
+        case 0x08383aacu:
+        {
+            if (name.beginsWith(BuiltInName::acos))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_acos_3B;
+            }
+            break;
+        }
+        case 0x0838a17eu:
+        {
+            if (name.beginsWith(BuiltInName::ceil))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_ceil_2B;
+            }
+            break;
+        }
+        case 0x0838ac89u:
+        {
+            if (name.beginsWith(BuiltInName::exp2))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_exp2_3B;
+            }
+            break;
+        }
+        case 0x0838dc31u:
+        {
+            if (name.beginsWith(BuiltInName::sqrt))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_sqrt_0B;
+            }
+            break;
+        }
+        case 0x08396a55u:
+        {
+            if (name.beginsWith(BuiltInName::acos))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_acos_2B;
+            }
+            break;
+        }
+        case 0x0839daf2u:
+        {
+            if (name.beginsWith(BuiltInName::exp2))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_exp2_0B;
+            }
+            break;
+        }
+        case 0x0839e751u:
+        {
+            if (name.beginsWith(BuiltInName::acos))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_acos_1B;
+            }
+            break;
+        }
+        case 0x0839f1a7u:
+        {
+            if (name.beginsWith(BuiltInName::ceil))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_ceil_3B;
+            }
+            break;
+        }
+        case 0x083a07bau:
+        {
+            if (name.beginsWith(BuiltInName::sqrt))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_sqrt_3B;
+            }
+            break;
+        }
+        case 0x083a7922u:
+        {
+            if (name.beginsWith(BuiltInName::ceil))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_ceil_0B;
+            }
+            break;
+        }
+        case 0x083aea5fu:
+        {
+            if (name.beginsWith(BuiltInName::atan))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_atan_2B;
+            }
+            break;
+        }
+        case 0x083af266u:
+        {
+            if (name.beginsWith(BuiltInName::sign))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_sign_1B;
+            }
+            break;
+        }
+        case 0x083afbc8u:
+        {
+            if (name.beginsWith(BuiltInName::acos))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_acos_0B;
+            }
+            break;
+        }
+        case 0x083b2b93u:
+        {
+            if (name.beginsWith(BuiltInName::exp2))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_exp2_1B;
+            }
+            break;
+        }
+        case 0x083b577bu:
+        {
+            if (name.beginsWith(BuiltInName::sqrt))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_sqrt_2B;
+            }
+            break;
+        }
+        case 0x083b7e52u:
+        {
+            if (name.beginsWith(BuiltInName::atan))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_atan_1B;
+            }
+            break;
+        }
+        case 0x083bcf76u:
+        {
+            if (name.beginsWith(BuiltInName::sqrt))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_sqrt_1B;
+            }
+            break;
+        }
+        case 0x083c1fc5u:
+        {
+            if (name.beginsWith(BuiltInName::sign))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_sign_2B;
+            }
+            break;
+        }
+        case 0x083c624bu:
+        {
+            if (name.beginsWith(BuiltInName::atan))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_atan_0B;
+            }
+            break;
+        }
+        case 0x083ca453u:
+        {
+            if (name.beginsWith(BuiltInName::asin))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_asin_0B;
+            }
+            break;
+        }
+        case 0x083cc6e1u:
+        {
+            if (name.beginsWith(BuiltInName::log2))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_log2_2B;
+            }
+            break;
+        }
+        case 0x083d6eacu:
+        {
+            if (name.beginsWith(BuiltInName::sign))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_sign_3B;
+            }
+            break;
+        }
+        case 0x083dac10u:
+        {
+            if (name.beginsWith(BuiltInName::atan))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_atan_3B;
+            }
+            break;
+        }
+        case 0x083dd4deu:
+        {
+            if (name.beginsWith(BuiltInName::sign))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_sign_0B;
+            }
+            break;
+        }
+        case 0x083df752u:
+        {
+            if (name.beginsWith(BuiltInName::asin))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_asin_1B;
+            }
+            break;
+        }
+        case 0x083e1b7au:
+        {
+            if (name.beginsWith(BuiltInName::log2))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_log2_1B;
+            }
+            break;
+        }
+        case 0x083e6948u:
+        {
+            if (name.beginsWith(BuiltInName::asin))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_asin_2B;
+            }
+            break;
+        }
+        case 0x083f4babu:
+        {
+            if (name.beginsWith(BuiltInName::log2))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_log2_0B;
+            }
+            break;
+        }
+        case 0x083f6552u:
+        {
+            if (name.beginsWith(BuiltInName::asin))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_asin_3B;
+            }
+            break;
+        }
+        case 0x083f6afdu:
+        {
+            if (name.beginsWith(BuiltInName::ceil))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_ceil_1B;
+            }
+            break;
+        }
+        case 0x083f8b90u:
+        {
+            if (name.beginsWith(BuiltInName::exp2))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_exp2_2B;
+            }
+            break;
+        }
+        case 0x083fd32eu:
+        {
+            if (name.beginsWith(BuiltInName::log2))
+            {
+                ASSERT(name.length() == 7);
+                return &BuiltInFunction::kFunction_log2_3B;
+            }
+            break;
+        }
+        case 0x08482806u:
+        {
+            if (name.beginsWith(BuiltInName::atan))
+            {
+                ASSERT(name.length() == 9);
+                return &BuiltInFunction::kFunction_atan_3B3B;
+            }
+            break;
+        }
+        case 0x08491304u:
+        {
+            if (name.beginsWith(BuiltInName::step))
+            {
+                ASSERT(name.length() == 9);
+                return &BuiltInFunction::kFunction_step_0B1B;
+            }
+            break;
+        }
+        case 0x0849bcfdu:
+        {
+            if (name.beginsWith(BuiltInName::step))
+            {
+                ASSERT(name.length() == 9);
+                return &BuiltInFunction::kFunction_step_2B2B;
+            }
+            break;
+        }
+        case 0x084aa6bfu:
+        {
+            if (name.beginsWith(BuiltInName::atan))
+            {
+                ASSERT(name.length() == 9);
+                return &BuiltInFunction::kFunction_atan_1B1B;
+            }
+            break;
+        }
+        case 0x084c10fau:
+        {
+            if (name.beginsWith(BuiltInName::atan))
+            {
+                ASSERT(name.length() == 9);
+                return &BuiltInFunction::kFunction_atan_0B0B;
+            }
+            break;
+        }
+        case 0x084c9765u:
+        {
+            if (name.beginsWith(BuiltInName::step))
+            {
+                ASSERT(name.length() == 9);
+                return &BuiltInFunction::kFunction_step_1B1B;
+            }
+            break;
+        }
+        case 0x084e7af1u:
+        {
+            if (name.beginsWith(BuiltInName::step))
+            {
+                ASSERT(name.length() == 9);
+                return &BuiltInFunction::kFunction_step_3B3B;
+            }
+            break;
+        }
+        case 0x084e7be4u:
+        {
+            if (name.beginsWith(BuiltInName::step))
+            {
+                ASSERT(name.length() == 9);
+                return &BuiltInFunction::kFunction_step_0B0B;
+            }
+            break;
+        }
+        case 0x084ec1e6u:
+        {
+            if (name.beginsWith(BuiltInName::step))
+            {
+                ASSERT(name.length() == 9);
+                return &BuiltInFunction::kFunction_step_0B3B;
+            }
+            break;
+        }
+        case 0x084ee899u:
+        {
+            if (name.beginsWith(BuiltInName::atan))
+            {
+                ASSERT(name.length() == 9);
+                return &BuiltInFunction::kFunction_atan_2B2B;
+            }
+            break;
+        }
+        case 0x084feda7u:
+        {
+            if (name.beginsWith(BuiltInName::step))
+            {
+                ASSERT(name.length() == 9);
+                return &BuiltInFunction::kFunction_step_0B2B;
+            }
+            break;
+        }
+        case 0x0a402a9cu:
+        {
+            if (name.beginsWith(BuiltInName::fract))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_fract_0B;
+            }
+            break;
+        }
+        case 0x0a41745fu:
+        {
+            if (name.beginsWith(BuiltInName::fract))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_fract_3B;
+            }
+            break;
+        }
+        case 0x0a42a596u:
+        {
+            if (name.beginsWith(BuiltInName::fract))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_fract_2B;
+            }
+            break;
+        }
+        case 0x0a43465eu:
+        {
+            if (name.beginsWith(BuiltInName::floor))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_floor_0B;
+            }
+            break;
+        }
+        case 0x0a43be63u:
+        {
+            if (name.beginsWith(BuiltInName::floor))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_floor_3B;
+            }
+            break;
+        }
+        case 0x0a44da6bu:
+        {
+            if (name.beginsWith(BuiltInName::floor))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_floor_2B;
+            }
+            break;
+        }
+        case 0x0a45ecc0u:
+        {
+            if (name.beginsWith(BuiltInName::floor))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_floor_1B;
+            }
+            break;
+        }
+        case 0x0a4726f2u:
+        {
+            if (name.beginsWith(BuiltInName::fract))
+            {
+                ASSERT(name.length() == 8);
+                return &BuiltInFunction::kFunction_fract_1B;
+            }
+            break;
+        }
+        case 0x0a513a26u:
+        {
+            if (name.beginsWith(BuiltInName::equal))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_equal_3E3E;
+            }
+            break;
+        }
+        case 0x0a51bddcu:
+        {
+            if (name.beginsWith(BuiltInName::equal))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_equal_3B3B;
+            }
+            break;
+        }
+        case 0x0a527d10u:
+        {
+            if (name.beginsWith(BuiltInName::cross))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_cross_2B2B;
+            }
+            break;
+        }
+        case 0x0a542036u:
+        {
+            if (name.beginsWith(BuiltInName::equal))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_equal_2C2C;
+            }
+            break;
+        }
+        case 0x0a54c30cu:
+        {
+            if (name.beginsWith(BuiltInName::equal))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_equal_2B2B;
+            }
+            break;
+        }
+        case 0x0a554046u:
+        {
+            if (name.beginsWith(BuiltInName::equal))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_equal_1C1C;
+            }
+            break;
+        }
+        case 0x0a56874bu:
+        {
+            if (name.beginsWith(BuiltInName::equal))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_equal_3C3C;
+            }
+            break;
+        }
+        case 0x0a56fc88u:
+        {
+            if (name.beginsWith(BuiltInName::equal))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_equal_2E2E;
+            }
+            break;
+        }
+        case 0x0a5744dcu:
+        {
+            if (name.beginsWith(BuiltInName::equal))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_equal_1E1E;
+            }
+            break;
+        }
+        case 0x0a57a8f5u:
+        {
+            if (name.beginsWith(BuiltInName::equal))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_equal_1B1B;
+            }
+            break;
+        }
+        case 0x0a619e65u:
+        {
+            if (name.beginsWith(BuiltInName::clamp))
+            {
+                ASSERT(name.length() == 12);
+                return &BuiltInFunction::kFunction_clamp_3B3B3B;
+            }
+            break;
+        }
+        case 0x0a62e0c3u:
+        {
+            if (name == BuiltInName::clamp_1B0B0B)
+            {
+                return &BuiltInFunction::kFunction_clamp_1B0B0B;
+            }
+            break;
+        }
+        case 0x0a635d1au:
+        {
+            if (name == BuiltInName::clamp_1B1B1B)
+            {
+                return &BuiltInFunction::kFunction_clamp_1B1B1B;
+            }
+            break;
+        }
+        case 0x0a658fc9u:
+        {
+            if (name == BuiltInName::clamp_3B0B0B)
+            {
+                return &BuiltInFunction::kFunction_clamp_3B0B0B;
+            }
+            break;
+        }
+        case 0x0a65f6b4u:
+        {
+            if (name.beginsWith(BuiltInName::clamp))
+            {
+                ASSERT(name.length() == 12);
+                return &BuiltInFunction::kFunction_clamp_0B0B0B;
+            }
+            break;
+        }
+        case 0x0a6670deu:
+        {
+            if (name.beginsWith(BuiltInName::clamp))
+            {
+                ASSERT(name.length() == 12);
+                return &BuiltInFunction::kFunction_clamp_2B0B0B;
+            }
+            break;
+        }
+        case 0x0a679af4u:
+        {
+            if (name.beginsWith(BuiltInName::clamp))
+            {
+                ASSERT(name.length() == 12);
+                return &BuiltInFunction::kFunction_clamp_2B2B2B;
+            }
+            break;
+        }
+        case 0x0c48bffau:
+        {
+            if (name.beginsWith(BuiltInName::length))
+            {
+                ASSERT(name.length() == 9);
+                return &BuiltInFunction::kFunction_length_0B;
+            }
+            break;
+        }
+        case 0x0c4924f7u:
+        {
+            if (name.beginsWith(BuiltInName::length))
+            {
+                ASSERT(name.length() == 9);
+                return &BuiltInFunction::kFunction_length_3B;
+            }
+            break;
+        }
+        case 0x0c4a38b6u:
+        {
+            if (name.beginsWith(BuiltInName::length))
+            {
+                ASSERT(name.length() == 9);
+                return &BuiltInFunction::kFunction_length_2B;
+            }
+            break;
+        }
+        case 0x0c4f6cbbu:
+        {
+            if (name.beginsWith(BuiltInName::length))
+            {
+                ASSERT(name.length() == 9);
+                return &BuiltInFunction::kFunction_length_1B;
+            }
+            break;
+        }
+        case 0x0e507f22u:
+        {
+            if (name.beginsWith(BuiltInName::degrees))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_degrees_2B;
+            }
+            break;
+        }
+        case 0x0e519bd4u:
+        {
+            if (name.beginsWith(BuiltInName::degrees))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_degrees_3B;
+            }
+            break;
+        }
+        case 0x0e52b187u:
+        {
+            if (name.beginsWith(BuiltInName::degrees))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_degrees_0B;
+            }
+            break;
+        }
+        case 0x0e52e500u:
+        {
+            if (name.beginsWith(BuiltInName::radians))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_radians_0B;
+            }
+            break;
+        }
+        case 0x0e537b7au:
+        {
+            if (name.beginsWith(BuiltInName::radians))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_radians_3B;
+            }
+            break;
+        }
+        case 0x0e541edeu:
+        {
+            if (name.beginsWith(BuiltInName::degrees))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_degrees_1B;
+            }
+            break;
+        }
+        case 0x0e547683u:
+        {
+            if (name.beginsWith(BuiltInName::radians))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_radians_2B;
+            }
+            break;
+        }
+        case 0x0e55ac28u:
+        {
+            if (name.beginsWith(BuiltInName::radians))
+            {
+                ASSERT(name.length() == 10);
+                return &BuiltInFunction::kFunction_radians_1B;
+            }
+            break;
+        }
+        case 0x0e620f44u:
+        {
+            if (name.beginsWith(BuiltInName::reflect))
+            {
+                ASSERT(name.length() == 12);
+                return &BuiltInFunction::kFunction_reflect_2B2B;
+            }
+            break;
+        }
+        case 0x0e631c50u:
+        {
+            if (name.beginsWith(BuiltInName::reflect))
+            {
+                ASSERT(name.length() == 12);
+                return &BuiltInFunction::kFunction_reflect_3B3B;
+            }
+            break;
+        }
+        case 0x0e63358eu:
+        {
+            if (name.beginsWith(BuiltInName::reflect))
+            {
+                ASSERT(name.length() == 12);
+                return &BuiltInFunction::kFunction_reflect_0B0B;
+            }
+            break;
+        }
+        case 0x0e665b7bu:
+        {
+            if (name.beginsWith(BuiltInName::reflect))
+            {
+                ASSERT(name.length() == 12);
+                return &BuiltInFunction::kFunction_reflect_1B1B;
+            }
+            break;
+        }
+        case 0x0e706684u:
+        {
+            if (name.beginsWith(BuiltInName::refract))
+            {
+                ASSERT(name.length() == 14);
+                return &BuiltInFunction::kFunction_refract_1B1B0B;
+            }
+            break;
+        }
+        case 0x0e71a4fcu:
+        {
+            if (name.beginsWith(BuiltInName::refract))
+            {
+                ASSERT(name.length() == 14);
+                return &BuiltInFunction::kFunction_refract_2B2B0B;
+            }
+            break;
+        }
+        case 0x0e71b28du:
+        {
+            if (name == BuiltInName::refract_3B3B0B)
+            {
+                return &BuiltInFunction::kFunction_refract_3B3B0B;
+            }
+            break;
+        }
+        case 0x0e73b594u:
+        {
+            if (name.beginsWith(BuiltInName::refract))
+            {
+                ASSERT(name.length() == 14);
+                return &BuiltInFunction::kFunction_refract_0B0B0B;
+            }
+            break;
+        }
+        case 0x1068425fu:
+        {
+            if (name.beginsWith(BuiltInName::distance))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_distance_3B3B;
+            }
+            break;
+        }
+        case 0x1068c0bfu:
+        {
+            if (name.beginsWith(BuiltInName::distance))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_distance_2B2B;
+            }
+            break;
+        }
+        case 0x1068f060u:
+        {
+            if (name.beginsWith(BuiltInName::notEqual))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_notEqual_1E1E;
+            }
+            break;
+        }
+        case 0x10695fe7u:
+        {
+            if (name.beginsWith(BuiltInName::notEqual))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_notEqual_2E2E;
+            }
+            break;
+        }
+        case 0x1069b2c0u:
+        {
+            if (name.beginsWith(BuiltInName::lessThan))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_lessThan_1B1B;
+            }
+            break;
+        }
+        case 0x106a110cu:
+        {
+            if (name.beginsWith(BuiltInName::lessThan))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_lessThan_3C3C;
+            }
+            break;
+        }
+        case 0x106a63f2u:
+        {
+            if (name.beginsWith(BuiltInName::notEqual))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_notEqual_2C2C;
+            }
+            break;
+        }
+        case 0x106a713eu:
+        {
+            if (name.beginsWith(BuiltInName::lessThan))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_lessThan_2B2B;
+            }
+            break;
+        }
+        case 0x106ade94u:
+        {
+            if (name.beginsWith(BuiltInName::notEqual))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_notEqual_1B1B;
+            }
+            break;
+        }
+        case 0x106b25c9u:
+        {
+            if (name.beginsWith(BuiltInName::notEqual))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_notEqual_1C1C;
+            }
+            break;
+        }
+        case 0x106b4468u:
+        {
+            if (name.beginsWith(BuiltInName::lessThan))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_lessThan_1C1C;
+            }
+            break;
+        }
+        case 0x106b8219u:
+        {
+            if (name.beginsWith(BuiltInName::notEqual))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_notEqual_3B3B;
+            }
+            break;
+        }
+        case 0x106bc4fcu:
+        {
+            if (name.beginsWith(BuiltInName::notEqual))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_notEqual_3E3E;
+            }
+            break;
+        }
+        case 0x106caf4fu:
+        {
+            if (name.beginsWith(BuiltInName::distance))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_distance_0B0B;
+            }
+            break;
+        }
+        case 0x106d2c39u:
+        {
+            if (name.beginsWith(BuiltInName::lessThan))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_lessThan_3B3B;
+            }
+            break;
+        }
+        case 0x106dabccu:
+        {
+            if (name.beginsWith(BuiltInName::notEqual))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_notEqual_2B2B;
+            }
+            break;
+        }
+        case 0x106eaf65u:
+        {
+            if (name.beginsWith(BuiltInName::notEqual))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_notEqual_3C3C;
+            }
+            break;
+        }
+        case 0x106faaeau:
+        {
+            if (name.beginsWith(BuiltInName::lessThan))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_lessThan_2C2C;
+            }
+            break;
+        }
+        case 0x106ff564u:
+        {
+            if (name.beginsWith(BuiltInName::distance))
+            {
+                ASSERT(name.length() == 13);
+                return &BuiltInFunction::kFunction_distance_1B1B;
+            }
+            break;
+        }
+        case 0x126235c4u:
+        {
+            if (name.beginsWith(BuiltInName::normalize))
+            {
+                ASSERT(name.length() == 12);
+                return &BuiltInFunction::kFunction_normalize_1B;
+            }
+            break;
+        }
+        case 0x12635a67u:
+        {
+            if (name.beginsWith(BuiltInName::normalize))
+            {
+                ASSERT(name.length() == 12);
+                return &BuiltInFunction::kFunction_normalize_2B;
+            }
+            break;
+        }
+        case 0x1264aa3eu:
+        {
+            if (name.beginsWith(BuiltInName::normalize))
+            {
+                ASSERT(name.length() == 12);
+                return &BuiltInFunction::kFunction_normalize_3B;
+            }
+            break;
+        }
+        case 0x12650243u:
+        {
+            if (name.beginsWith(BuiltInName::normalize))
+            {
+                ASSERT(name.length() == 12);
+                return &BuiltInFunction::kFunction_normalize_0B;
+            }
+            break;
+        }
+        case 0x14888e72u:
+        {
+            if (name.beginsWith(BuiltInName::smoothstep))
+            {
+                ASSERT(name.length() == 17);
+                return &BuiltInFunction::kFunction_smoothstep_0B0B1B;
+            }
+            break;
+        }
+        case 0x1489436du:
+        {
+            if (name == BuiltInName::smoothstep_1B1B1B)
+            {
+                return &BuiltInFunction::kFunction_smoothstep_1B1B1B;
+            }
+            break;
+        }
+        case 0x1489bfb6u:
+        {
+            if (name == BuiltInName::smoothstep_3B3B3B)
+            {
+                return &BuiltInFunction::kFunction_smoothstep_3B3B3B;
+            }
+            break;
+        }
+        case 0x148a33b9u:
+        {
+            if (name.beginsWith(BuiltInName::smoothstep))
+            {
+                ASSERT(name.length() == 17);
+                return &BuiltInFunction::kFunction_smoothstep_2B2B2B;
+            }
+            break;
+        }
+        case 0x148de9b5u:
+        {
+            if (name.beginsWith(BuiltInName::smoothstep))
+            {
+                ASSERT(name.length() == 17);
+                return &BuiltInFunction::kFunction_smoothstep_0B0B0B;
+            }
+            break;
+        }
+        case 0x148e5c11u:
+        {
+            if (name.beginsWith(BuiltInName::smoothstep))
+            {
+                ASSERT(name.length() == 17);
+                return &BuiltInFunction::kFunction_smoothstep_0B0B3B;
+            }
+            break;
+        }
+        case 0x148f7bf9u:
+        {
+            if (name.beginsWith(BuiltInName::smoothstep))
+            {
+                ASSERT(name.length() == 17);
+                return &BuiltInFunction::kFunction_smoothstep_0B0B2B;
+            }
+            break;
+        }
+        case 0x1670b92du:
+        {
+            if (name.beginsWith(BuiltInName::inversesqrt))
+            {
+                ASSERT(name.length() == 14);
+                return &BuiltInFunction::kFunction_inversesqrt_2B;
+            }
+            break;
+        }
+        case 0x1671d38eu:
+        {
+            if (name.beginsWith(BuiltInName::inversesqrt))
+            {
+                ASSERT(name.length() == 14);
+                return &BuiltInFunction::kFunction_inversesqrt_1B;
+            }
+            break;
+        }
+        case 0x16772b69u:
+        {
+            if (name.beginsWith(BuiltInName::inversesqrt))
+            {
+                ASSERT(name.length() == 14);
+                return &BuiltInFunction::kFunction_inversesqrt_0B;
+            }
+            break;
+        }
+        case 0x1677857cu:
+        {
+            if (name.beginsWith(BuiltInName::inversesqrt))
+            {
+                ASSERT(name.length() == 14);
+                return &BuiltInFunction::kFunction_inversesqrt_3B;
+            }
+            break;
+        }
+        case 0x16817df9u:
+        {
+            if (name.beginsWith(BuiltInName::greaterThan))
+            {
+                ASSERT(name.length() == 16);
+                return &BuiltInFunction::kFunction_greaterThan_1B1B;
+            }
+            break;
+        }
+        case 0x1681b963u:
+        {
+            if (name.beginsWith(BuiltInName::greaterThan))
+            {
+                ASSERT(name.length() == 16);
+                return &BuiltInFunction::kFunction_greaterThan_3C3C;
+            }
+            break;
+        }
+        case 0x16829d5du:
+        {
+            if (name.beginsWith(BuiltInName::greaterThan))
+            {
+                ASSERT(name.length() == 16);
+                return &BuiltInFunction::kFunction_greaterThan_3B3B;
+            }
+            break;
+        }
+        case 0x16853112u:
+        {
+            if (name.beginsWith(BuiltInName::greaterThan))
+            {
+                ASSERT(name.length() == 16);
+                return &BuiltInFunction::kFunction_greaterThan_2B2B;
+            }
+            break;
+        }
+        case 0x1685d025u:
+        {
+            if (name.beginsWith(BuiltInName::greaterThan))
+            {
+                ASSERT(name.length() == 16);
+                return &BuiltInFunction::kFunction_greaterThan_2C2C;
+            }
+            break;
+        }
+        case 0x1685db46u:
+        {
+            if (name.beginsWith(BuiltInName::greaterThan))
+            {
+                ASSERT(name.length() == 16);
+                return &BuiltInFunction::kFunction_greaterThan_1C1C;
+            }
+            break;
+        }
+        case 0x1690b84du:
+        {
+            if (name == BuiltInName::faceforward_3B3B3B)
+            {
+                return &BuiltInFunction::kFunction_faceforward_3B3B3B;
+            }
+            break;
+        }
+        case 0x1691c40bu:
+        {
+            if (name == BuiltInName::faceforward_1B1B1B)
+            {
+                return &BuiltInFunction::kFunction_faceforward_1B1B1B;
+            }
+            break;
+        }
+        case 0x1696babeu:
+        {
+            if (name == BuiltInName::faceforward_2B2B2B)
+            {
+                return &BuiltInFunction::kFunction_faceforward_2B2B2B;
+            }
+            break;
+        }
+        case 0x1697cde8u:
+        {
+            if (name.beginsWith(BuiltInName::faceforward))
+            {
+                ASSERT(name.length() == 18);
+                return &BuiltInFunction::kFunction_faceforward_0B0B0B;
+            }
+            break;
+        }
+        case 0x1a9481a8u:
+        {
+            if (name.beginsWith(BuiltInName::lessThanEqual))
+            {
+                ASSERT(name.length() == 18);
+                return &BuiltInFunction::kFunction_lessThanEqual_2C2C;
+            }
+            break;
+        }
+        case 0x1a94a164u:
+        {
+            if (name.beginsWith(BuiltInName::lessThanEqual))
+            {
+                ASSERT(name.length() == 18);
+                return &BuiltInFunction::kFunction_lessThanEqual_3C3C;
+            }
+            break;
+        }
+        case 0x1a95c72au:
+        {
+            if (name.beginsWith(BuiltInName::lessThanEqual))
+            {
+                ASSERT(name.length() == 18);
+                return &BuiltInFunction::kFunction_lessThanEqual_1B1B;
+            }
+            break;
+        }
+        case 0x1a9642f7u:
+        {
+            if (name.beginsWith(BuiltInName::lessThanEqual))
+            {
+                ASSERT(name.length() == 18);
+                return &BuiltInFunction::kFunction_lessThanEqual_3B3B;
+            }
+            break;
+        }
+        case 0x1a977782u:
+        {
+            if (name.beginsWith(BuiltInName::lessThanEqual))
+            {
+                ASSERT(name.length() == 18);
+                return &BuiltInFunction::kFunction_lessThanEqual_1C1C;
+            }
+            break;
+        }
+        case 0x1a97d055u:
+        {
+            if (name.beginsWith(BuiltInName::lessThanEqual))
+            {
+                ASSERT(name.length() == 18);
+                return &BuiltInFunction::kFunction_lessThanEqual_2B2B;
+            }
+            break;
+        }
+        case 0x1c993bdfu:
+        {
+            if (name.beginsWith(BuiltInName::matrixCompMult))
+            {
+                ASSERT(name.length() == 19);
+                return &BuiltInFunction::kFunction_matrixCompMult_5B5B;
+            }
+            break;
+        }
+        case 0x1c9b357cu:
+        {
+            if (name.beginsWith(BuiltInName::matrixCompMult))
+            {
+                ASSERT(name.length() == 19);
+                return &BuiltInFunction::kFunction_matrixCompMult_FBFB;
+            }
+            break;
+        }
+        case 0x1c9e72dbu:
+        {
+            if (name.beginsWith(BuiltInName::matrixCompMult))
+            {
+                ASSERT(name.length() == 19);
+                return &BuiltInFunction::kFunction_matrixCompMult_ABAB;
+            }
+            break;
+        }
+        case 0x20ab1dc0u:
+        {
+            if (name.beginsWith(BuiltInName::greaterThanEqual))
+            {
+                ASSERT(name.length() == 21);
+                return &BuiltInFunction::kFunction_greaterThanEqual_2C2C;
+            }
+            break;
+        }
+        case 0x20acdd3au:
+        {
+            if (name.beginsWith(BuiltInName::greaterThanEqual))
+            {
+                ASSERT(name.length() == 21);
+                return &BuiltInFunction::kFunction_greaterThanEqual_1B1B;
+            }
+            break;
+        }
+        case 0x20ad192cu:
+        {
+            if (name.beginsWith(BuiltInName::greaterThanEqual))
+            {
+                ASSERT(name.length() == 21);
+                return &BuiltInFunction::kFunction_greaterThanEqual_3C3C;
+            }
+            break;
+        }
+        case 0x20adfc96u:
+        {
+            if (name.beginsWith(BuiltInName::greaterThanEqual))
+            {
+                ASSERT(name.length() == 21);
+                return &BuiltInFunction::kFunction_greaterThanEqual_3B3B;
+            }
+            break;
+        }
+        case 0x20ae6ffbu:
+        {
+            if (name.beginsWith(BuiltInName::greaterThanEqual))
+            {
+                ASSERT(name.length() == 21);
+                return &BuiltInFunction::kFunction_greaterThanEqual_2B2B;
+            }
+            break;
+        }
+        case 0x20af1dd4u:
+        {
+            if (name.beginsWith(BuiltInName::greaterThanEqual))
+            {
+                ASSERT(name.length() == 21);
+                return &BuiltInFunction::kFunction_greaterThanEqual_1C1C;
+            }
+            break;
+        }
+        case 0x7e6af03cu:
+        {
+            if (name == BuiltInName::gl_DepthRange)
+            {
+                return mVar_gl_DepthRange;
+            }
+            break;
+        }
+        case 0x7e8ab02eu:
+        {
+            if (name == BuiltInName::gl_MaxDrawBuffers)
+            {
+                return mVar_gl_MaxDrawBuffers;
+            }
+            break;
+        }
+        case 0x7e9ad799u:
+        {
+            if (name == BuiltInName::gl_MaxVertexAttribs)
+            {
+                return mVar_gl_MaxVertexAttribs;
+            }
+            break;
+        }
+        case 0x7ebaa8e5u:
+        {
+            if (name == BuiltInName::gl_MaxTextureImageUnits)
+            {
+                return mVar_gl_MaxTextureImageUnits;
+            }
+            break;
+        }
+        case 0x7ebeff64u:
+        {
+            if (name == BuiltInName::gl_DepthRangeParameters)
+            {
+                return mVar_gl_DepthRangeParameters;
+            }
+            break;
+        }
+        case 0x7ed35151u:
+        {
+            if (name == BuiltInName::gl_MaxVertexUniformVectors)
+            {
+                return mVar_gl_MaxVertexUniformVectors;
+            }
+            break;
+        }
+        case 0x7ee45ba1u:
+        {
+            if (name == BuiltInName::gl_MaxFragmentUniformVectors)
+            {
+                return mVar_gl_MaxFragmentUniformVectors;
+            }
+            break;
+        }
+        case 0x7eea039au:
+        {
+            if (name == BuiltInName::gl_MaxVertexTextureImageUnits)
+            {
+                return mVar_gl_MaxVertexTextureImageUnits;
+            }
+            break;
+        }
+        case 0x7ef1e608u:
+        {
+            if (name == BuiltInName::gl_MaxDualSourceDrawBuffersEXT)
+            {
+                return mVar_gl_MaxDualSourceDrawBuffersEXT;
+            }
+            break;
+        }
+        case 0x7ef84293u:
+        {
+            if (name == BuiltInName::gl_MaxCombinedTextureImageUnits)
+            {
+                return mVar_gl_MaxCombinedTextureImageUnits;
+            }
+            break;
+        }
+    }
+    if (mShaderType == GL_FRAGMENT_SHADER)
+    {
+        switch (nameHash)
+        {
+            case 0x7e64c010u:
+            {
+                if (name == BuiltInName::gl_FragCoord)
+                {
+                    return &BuiltInVariable::kVar_gl_FragCoord;
+                }
+                break;
+            }
+            case 0x7e6c2088u:
+            {
+                if (name == BuiltInName::gl_PointCoord)
+                {
+                    return &BuiltInVariable::kVar_gl_PointCoord;
+                }
+                break;
+            }
+            case 0x7e73011eu:
+            {
+                if (name == BuiltInName::gl_FrontFacing)
+                {
+                    return &BuiltInVariable::kVar_gl_FrontFacing;
+                }
+                break;
+            }
+        }
+    }
+    if (mShaderType == GL_VERTEX_SHADER)
+    {
+        switch (nameHash)
+        {
+            case 0x7e580bc5u:
+            {
+                if (name == BuiltInName::gl_Position)
+                {
+                    return &BuiltInVariable::kVar_gl_Position;
+                }
+                break;
+            }
+            case 0x7e63931cu:
+            {
+                if (name == BuiltInName::gl_PointSize)
+                {
+                    return &BuiltInVariable::kVar_gl_PointSize;
+                }
+                break;
+            }
+        }
+    }
+    return nullptr;
+}
+
+const UnmangledBuiltIn *TSymbolTable::getUnmangledBuiltInForShaderVersion(
+    const ImmutableString &name,
+    int shaderVersion)
+{
+    if (name.length() > 26)
+    {
+        return nullptr;
+    }
+    uint32_t nameHash = name.mangledNameHash();
+    if (shaderVersion >= 310)
+    {
+        switch (nameHash)
+        {
+            case 0x7e2c727fu:
+            {
+                if (name == BuiltInName::ldexp)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e2d0692u:
+            {
+                if (name == BuiltInName::frexp)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e399596u:
+            {
+                if (name == BuiltInName::findLSB)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e3bdf3fu:
+            {
+                if (name == BuiltInName::findMSB)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e41283bu:
+            {
+                if (name == BuiltInName::bitCount)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e4690b3u:
+            {
+                if (name == BuiltInName::atomicOr)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e4800e3u:
+            {
+                if (name == BuiltInName::atomicAdd)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e4893a8u:
+            {
+                if (name == BuiltInName::atomicMax)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e49061fu:
+            {
+                if (name == BuiltInName::atomicMin)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e4a45b6u:
+            {
+                if (name == BuiltInName::imageLoad)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e4b6656u:
+            {
+                if (name == BuiltInName::imageSize)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e4dea77u:
+            {
+                if (name == BuiltInName::atomicXor)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e4e5094u:
+            {
+                if (name == BuiltInName::uaddCarry)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e4f21aeu:
+            {
+                if (name == BuiltInName::atomicAnd)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e5237e1u:
+            {
+                if (name == BuiltInName::texelFetch)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e5276efu:
+            {
+                if (name == BuiltInName::imageStore)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e55de86u:
+            {
+                if (name == BuiltInName::usubBorrow)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e6273e5u:
+            {
+                if (name == BuiltInName::packSnorm4x8)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e62a9a0u:
+            {
+                if (name == BuiltInName::imulExtended)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e657e29u:
+            {
+                if (name == BuiltInName::packUnorm4x8)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e6746f4u:
+            {
+                if (name == BuiltInName::umulExtended)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e69d0dbu:
+            {
+                if (name == BuiltInName::memoryBarrier)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e6d0f32u:
+            {
+                if (name == BuiltInName::textureGather)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e6e00a5u:
+            {
+                if (name == BuiltInName::atomicCounter)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e71963eu:
+            {
+                if (name == BuiltInName::unpackUnorm4x8)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e73f1d1u:
+            {
+                if (name == BuiltInName::unpackSnorm4x8)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e75cfb1u:
+            {
+                if (name == BuiltInName::atomicExchange)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e778ffcu:
+            {
+                if (name == BuiltInName::atomicCompSwap)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e77c121u:
+            {
+                if (name == BuiltInName::bitfieldInsert)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e7f2cb2u:
+            {
+                if (name == BuiltInName::bitfieldReverse)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e7fa0c1u:
+            {
+                if (name == BuiltInName::bitfieldExtract)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e9269d7u:
+            {
+                if (name == BuiltInName::memoryBarrierImage)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e9b7f32u:
+            {
+                if (name == BuiltInName::memoryBarrierBuffer)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e9d8ad9u:
+            {
+                if (name == BuiltInName::textureGatherOffset)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7eb323ddu:
+            {
+                if (name == BuiltInName::atomicCounterIncrement)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7eb6aed0u:
+            {
+                if (name == BuiltInName::atomicCounterDecrement)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7ed5b06bu:
+            {
+                if (name == BuiltInName::memoryBarrierAtomicCounter)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+        }
+        if (mShaderType == GL_COMPUTE_SHADER)
+        {
+            switch (nameHash)
+            {
+                case 0x7e39f4e9u:
+                {
+                    if (name == BuiltInName::barrier)
+                    {
+                        return &UnmangledBuiltIns::UNDEFINED;
+                    }
+                    break;
+                }
+                case 0x7e93c6b9u:
+                {
+                    if (name == BuiltInName::groupMemoryBarrier)
+                    {
+                        return &UnmangledBuiltIns::UNDEFINED;
+                    }
+                    break;
+                }
+                case 0x7e9f4b19u:
+                {
+                    if (name == BuiltInName::memoryBarrierShared)
+                    {
+                        return &UnmangledBuiltIns::UNDEFINED;
+                    }
+                    break;
+                }
+            }
+        }
+        if (mShaderType == GL_GEOMETRY_SHADER_EXT)
+        {
+            switch (nameHash)
+            {
+                case 0x7e55adc2u:
+                {
+                    if (name == BuiltInName::EmitVertex)
+                    {
+                        return &UnmangledBuiltIns::EXT_geometry_shader;
+                    }
+                    break;
+                }
+                case 0x7e65b2cau:
+                {
+                    if (name == BuiltInName::EndPrimitive)
+                    {
+                        return &UnmangledBuiltIns::EXT_geometry_shader;
+                    }
+                    break;
+                }
+            }
+        }
+    }
+    if (shaderVersion >= 300)
+    {
+        switch (nameHash)
+        {
+            case 0x7e19507bu:
+            {
+                if (name == BuiltInName::abs)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e1e492du:
+            {
+                if (name == BuiltInName::min)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e1ea71bu:
+            {
+                if (name == BuiltInName::mix)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e1ebe0eu:
+            {
+                if (name == BuiltInName::max)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e205c92u:
+            {
+                if (name == BuiltInName::tanh)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e206e40u:
+            {
+                if (name == BuiltInName::sign)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e209eadu:
+            {
+                if (name == BuiltInName::sinh)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e274509u:
+            {
+                if (name == BuiltInName::modf)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e27a4feu:
+            {
+                if (name == BuiltInName::cosh)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e28294fu:
+            {
+                if (name == BuiltInName::atanh)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e2924b8u:
+            {
+                if (name == BuiltInName::isinf)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e297347u:
+            {
+                if (name == BuiltInName::equal)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e2a7a64u:
+            {
+                if (name == BuiltInName::round)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e2d5dcbu:
+            {
+                if (name == BuiltInName::clamp)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e2d8df4u:
+            {
+                if (name == BuiltInName::isnan)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e2dcbc6u:
+            {
+                if (name == BuiltInName::asinh)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e2eab16u:
+            {
+                if (name == BuiltInName::trunc)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e2f67c3u:
+            {
+                if (name == BuiltInName::acosh)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e39ebd7u:
+            {
+                if (name == BuiltInName::texture)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e3d828cu:
+            {
+                if (name == BuiltInName::inverse)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e403a20u:
+            {
+                if (name == BuiltInName::lessThan)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e413f93u:
+            {
+                if (name == BuiltInName::notEqual)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e4d27c2u:
+            {
+                if (name == BuiltInName::rgb_2_yuv)
+                {
+                    return &UnmangledBuiltIns::EXT_YUV_target;
+                }
+                break;
+            }
+            case 0x7e4d323bu:
+            {
+                if (name == BuiltInName::roundEven)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e4e024cu:
+            {
+                if (name == BuiltInName::transpose)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e4e33aeu:
+            {
+                if (name == BuiltInName::yuv_2_rgb)
+                {
+                    return &UnmangledBuiltIns::EXT_YUV_target;
+                }
+                break;
+            }
+            case 0x7e501e0cu:
+            {
+                if (name == BuiltInName::textureLod)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e5237e1u:
+            {
+                if (name == BuiltInName::texelFetch)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e582ffcu:
+            {
+                if (name == BuiltInName::greaterThan)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e599347u:
+            {
+                if (name == BuiltInName::textureGrad)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e5ba531u:
+            {
+                if (name == BuiltInName::determinant)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e5caafbu:
+            {
+                if (name == BuiltInName::textureProj)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e5e217eu:
+            {
+                if (name == BuiltInName::textureSize)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e62daa3u:
+            {
+                if (name == BuiltInName::packHalf2x16)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e646b9bu:
+            {
+                if (name == BuiltInName::outerProduct)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e683586u:
+            {
+                if (name == BuiltInName::lessThanEqual)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e6a013du:
+            {
+                if (name == BuiltInName::packSnorm2x16)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e6b72b8u:
+            {
+                if (name == BuiltInName::packUnorm2x16)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e6c5187u:
+            {
+                if (name == BuiltInName::textureOffset)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e715db5u:
+            {
+                if (name == BuiltInName::unpackHalf2x16)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e759618u:
+            {
+                if (name == BuiltInName::floatBitsToInt)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e75ae2fu:
+            {
+                if (name == BuiltInName::textureProjLod)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e76bea7u:
+            {
+                if (name == BuiltInName::matrixCompMult)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e77fc97u:
+            {
+                if (name == BuiltInName::intBitsToFloat)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e792d39u:
+            {
+                if (name == BuiltInName::unpackUnorm2x16)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e7b6a0eu:
+            {
+                if (name == BuiltInName::unpackSnorm2x16)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e7bc1fdu:
+            {
+                if (name == BuiltInName::textureProjGrad)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e7e0e81u:
+            {
+                if (name == BuiltInName::uintBitsToFloat)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e7e5132u:
+            {
+                if (name == BuiltInName::floatBitsToUint)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e80919du:
+            {
+                if (name == BuiltInName::texelFetchOffset)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e81c71au:
+            {
+                if (name == BuiltInName::textureLodOffset)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e876cccu:
+            {
+                if (name == BuiltInName::greaterThanEqual)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e8b5832u:
+            {
+                if (name == BuiltInName::textureGradOffset)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e8d2d2du:
+            {
+                if (name == BuiltInName::textureProjOffset)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7ea0be08u:
+            {
+                if (name == BuiltInName::textureProjLodOffset)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7eac5717u:
+            {
+                if (name == BuiltInName::textureProjGradOffset)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+        }
+        if (mShaderType == GL_FRAGMENT_SHADER)
+        {
+            switch (nameHash)
+            {
+                case 0x7e2624d4u:
+                {
+                    if (name == BuiltInName::dFdy)
+                    {
+                        return &UnmangledBuiltIns::UNDEFINED;
+                    }
+                    break;
+                }
+                case 0x7e265ea7u:
+                {
+                    if (name == BuiltInName::dFdx)
+                    {
+                        return &UnmangledBuiltIns::UNDEFINED;
+                    }
+                    break;
+                }
+                case 0x7e324ea1u:
+                {
+                    if (name == BuiltInName::fwidth)
+                    {
+                        return &UnmangledBuiltIns::UNDEFINED;
+                    }
+                    break;
+                }
+            }
+        }
+    }
+    if (shaderVersion == 100)
+    {
+        switch (nameHash)
+        {
+            case 0x7e48c50cu:
+            {
+                if (name == BuiltInName::texture2D)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e5ffc48u:
+            {
+                if (name == BuiltInName::textureCube)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e69f545u:
+            {
+                if (name == BuiltInName::texture2DRect)
+                {
+                    return &UnmangledBuiltIns::ARB_texture_rectangle;
+                }
+                break;
+            }
+            case 0x7e6e3735u:
+            {
+                if (name == BuiltInName::texture2DProj)
+                {
+                    return &UnmangledBuiltIns::UNDEFINED;
+                }
+                break;
+            }
+            case 0x7e868a22u:
+            {
+                if (name == BuiltInName::texture2DGradEXT)
+                {
+                    return &UnmangledBuiltIns::EXT_shader_texture_lod;
+                }
+                break;
+            }
+            case 0x7e8b66e4u:
+            {
+                if (name == BuiltInName::texture2DRectProj)
+                {
+                    return &UnmangledBuiltIns::ARB_texture_rectangle;
+                }
+                break;
+            }
+            case 0x7e90fa5bu:
+            {
+                if (name == BuiltInName::textureCubeGradEXT)
+                {
+                    return &UnmangledBuiltIns::EXT_shader_texture_lod;
+                }
+                break;
+            }
+            case 0x7ea20b8fu:
+            {
+                if (name == BuiltInName::texture2DProjGradEXT)
+                {
+                    return &UnmangledBuiltIns::EXT_shader_texture_lod;
+                }
+                break;
+            }
+        }
+        if (mShaderType == GL_FRAGMENT_SHADER)
+        {
+            switch (nameHash)
+            {
+                case 0x7e2624d4u:
+                {
+                    if (name == BuiltInName::dFdyExt)
+                    {
+                        return &UnmangledBuiltIns::OES_standard_derivatives;
+                    }
+                    break;
+                }
+                case 0x7e265ea7u:
+                {
+                    if (name == BuiltInName::dFdxExt)
+                    {
+                        return &UnmangledBuiltIns::OES_standard_derivatives;
+                    }
+                    break;
+                }
+                case 0x7e324ea1u:
+                {
+                    if (name == BuiltInName::fwidthExt)
+                    {
+                        return &UnmangledBuiltIns::OES_standard_derivatives;
+                    }
+                    break;
+                }
+                case 0x7e7b843eu:
+                {
+                    if (name == BuiltInName::texture2DLodEXT)
+                    {
+                        return &UnmangledBuiltIns::EXT_shader_texture_lod;
+                    }
+                    break;
+                }
+                case 0x7e8b81cau:
+                {
+                    if (name == BuiltInName::textureCubeLodEXT)
+                    {
+                        return &UnmangledBuiltIns::EXT_shader_texture_lod;
+                    }
+                    break;
+                }
+                case 0x7e9ddba0u:
+                {
+                    if (name == BuiltInName::texture2DProjLodEXT)
+                    {
+                        return &UnmangledBuiltIns::EXT_shader_texture_lod;
+                    }
+                    break;
+                }
+            }
+        }
+        if (mShaderType == GL_VERTEX_SHADER)
+        {
+            switch (nameHash)
+            {
+                case 0x7e67c7ceu:
+                {
+                    if (name == BuiltInName::texture2DLod)
+                    {
+                        return &UnmangledBuiltIns::UNDEFINED;
+                    }
+                    break;
+                }
+                case 0x7e758eddu:
+                {
+                    if (name == BuiltInName::textureCubeLod)
+                    {
+                        return &UnmangledBuiltIns::UNDEFINED;
+                    }
+                    break;
+                }
+                case 0x7e819b90u:
+                {
+                    if (name == BuiltInName::texture2DProjLod)
+                    {
+                        return &UnmangledBuiltIns::UNDEFINED;
+                    }
+                    break;
+                }
+            }
+        }
+    }
+    switch (nameHash)
+    {
+        case 0x7e1892eeu:
+        {
+            if (name == BuiltInName::all)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e19507bu:
+        {
+            if (name == BuiltInName::abs)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e195106u:
+        {
+            if (name == BuiltInName::notFunc)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e197102u:
+        {
+            if (name == BuiltInName::any)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e19ebdbu:
+        {
+            if (name == BuiltInName::log)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e1acb4eu:
+        {
+            if (name == BuiltInName::pow)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e1b921cu:
+        {
+            if (name == BuiltInName::exp)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e1cf321u:
+        {
+            if (name == BuiltInName::tan)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e1e492du:
+        {
+            if (name == BuiltInName::min)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e1e8464u:
+        {
+            if (name == BuiltInName::dot)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e1ea71bu:
+        {
+            if (name == BuiltInName::mix)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e1ebe0eu:
+        {
+            if (name == BuiltInName::max)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e1eee70u:
+        {
+            if (name == BuiltInName::mod)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e1f0bccu:
+        {
+            if (name == BuiltInName::sin)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e1fdef3u:
+        {
+            if (name == BuiltInName::cos)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e203979u:
+        {
+            if (name == BuiltInName::atan)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e206e40u:
+        {
+            if (name == BuiltInName::sign)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e209ec1u:
+        {
+            if (name == BuiltInName::log2)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e21ff11u:
+        {
+            if (name == BuiltInName::acos)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e23152fu:
+        {
+            if (name == BuiltInName::ceil)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e23f4beu:
+        {
+            if (name == BuiltInName::sqrt)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e24bcdbu:
+        {
+            if (name == BuiltInName::exp2)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e26202fu:
+        {
+            if (name == BuiltInName::step)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e27ebd5u:
+        {
+            if (name == BuiltInName::asin)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e295733u:
+        {
+            if (name == BuiltInName::cross)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e297347u:
+        {
+            if (name == BuiltInName::equal)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e2d5dcbu:
+        {
+            if (name == BuiltInName::clamp)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e2dcb25u:
+        {
+            if (name == BuiltInName::floor)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e2f6df3u:
+        {
+            if (name == BuiltInName::fract)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e340894u:
+        {
+            if (name == BuiltInName::length)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e38233fu:
+        {
+            if (name == BuiltInName::refract)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e3c3cb3u:
+        {
+            if (name == BuiltInName::radians)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e3c8e91u:
+        {
+            if (name == BuiltInName::reflect)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e3d784cu:
+        {
+            if (name == BuiltInName::degrees)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e403a20u:
+        {
+            if (name == BuiltInName::lessThan)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e413f93u:
+        {
+            if (name == BuiltInName::notEqual)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e4161fau:
+        {
+            if (name == BuiltInName::distance)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e4e7aa5u:
+        {
+            if (name == BuiltInName::normalize)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e54a2cfu:
+        {
+            if (name == BuiltInName::smoothstep)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e582ffcu:
+        {
+            if (name == BuiltInName::greaterThan)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e5ae14bu:
+        {
+            if (name == BuiltInName::faceforward)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e5f4d0fu:
+        {
+            if (name == BuiltInName::inversesqrt)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e683586u:
+        {
+            if (name == BuiltInName::lessThanEqual)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e76bea7u:
+        {
+            if (name == BuiltInName::matrixCompMult)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+        case 0x7e876cccu:
+        {
+            if (name == BuiltInName::greaterThanEqual)
+            {
+                return &UnmangledBuiltIns::UNDEFINED;
+            }
+            break;
+        }
+    }
+    return nullptr;
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolTable_autogen.h
@@ -0,0 +1,78 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_builtin_symbols.py using data from builtin_variables.json and
+// builtin_function_declarations.txt.
+//
+// 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.
+//
+// SymbolTable_autogen.h:
+//   Autogenerated member variables of TSymbolTable.
+
+#ifndef COMPILER_TRANSLATOR_SYMBOLTABLE_AUTOGEN_H_
+#define COMPILER_TRANSLATOR_SYMBOLTABLE_AUTOGEN_H_
+
+namespace sh
+{
+
+class TSymbolTableBase
+{
+  protected:
+    TSymbolTableBase()                                  = default;
+    TStructure *mVar_gl_DepthRangeParameters            = nullptr;
+    TVariable *mVar_gl_DepthRange                       = nullptr;
+    TVariable *mVar_gl_MaxVertexAttribs                 = nullptr;
+    TVariable *mVar_gl_MaxVertexUniformVectors          = nullptr;
+    TVariable *mVar_gl_MaxVertexTextureImageUnits       = nullptr;
+    TVariable *mVar_gl_MaxCombinedTextureImageUnits     = nullptr;
+    TVariable *mVar_gl_MaxTextureImageUnits             = nullptr;
+    TVariable *mVar_gl_MaxFragmentUniformVectors        = nullptr;
+    TVariable *mVar_gl_MaxVaryingVectors                = nullptr;
+    TVariable *mVar_gl_MaxDrawBuffers                   = nullptr;
+    TVariable *mVar_gl_MaxDualSourceDrawBuffersEXT      = nullptr;
+    TVariable *mVar_gl_MaxVertexOutputVectors           = nullptr;
+    TVariable *mVar_gl_MaxFragmentInputVectors          = nullptr;
+    TVariable *mVar_gl_MinProgramTexelOffset            = nullptr;
+    TVariable *mVar_gl_MaxProgramTexelOffset            = nullptr;
+    TVariable *mVar_gl_MaxImageUnits                    = nullptr;
+    TVariable *mVar_gl_MaxVertexImageUniforms           = nullptr;
+    TVariable *mVar_gl_MaxFragmentImageUniforms         = nullptr;
+    TVariable *mVar_gl_MaxComputeImageUniforms          = nullptr;
+    TVariable *mVar_gl_MaxCombinedImageUniforms         = nullptr;
+    TVariable *mVar_gl_MaxCombinedShaderOutputResources = nullptr;
+    TVariable *mVar_gl_MaxComputeWorkGroupCount         = nullptr;
+    TVariable *mVar_gl_MaxComputeWorkGroupSize          = nullptr;
+    TVariable *mVar_gl_MaxComputeUniformComponents      = nullptr;
+    TVariable *mVar_gl_MaxComputeTextureImageUnits      = nullptr;
+    TVariable *mVar_gl_MaxComputeAtomicCounters         = nullptr;
+    TVariable *mVar_gl_MaxComputeAtomicCounterBuffers   = nullptr;
+    TVariable *mVar_gl_MaxVertexAtomicCounters          = nullptr;
+    TVariable *mVar_gl_MaxFragmentAtomicCounters        = nullptr;
+    TVariable *mVar_gl_MaxCombinedAtomicCounters        = nullptr;
+    TVariable *mVar_gl_MaxAtomicCounterBindings         = nullptr;
+    TVariable *mVar_gl_MaxVertexAtomicCounterBuffers    = nullptr;
+    TVariable *mVar_gl_MaxFragmentAtomicCounterBuffers  = nullptr;
+    TVariable *mVar_gl_MaxCombinedAtomicCounterBuffers  = nullptr;
+    TVariable *mVar_gl_MaxAtomicCounterBufferSize       = nullptr;
+    TVariable *mVar_gl_MaxGeometryInputComponents       = nullptr;
+    TVariable *mVar_gl_MaxGeometryOutputComponents      = nullptr;
+    TVariable *mVar_gl_MaxGeometryImageUniforms         = nullptr;
+    TVariable *mVar_gl_MaxGeometryTextureImageUnits     = nullptr;
+    TVariable *mVar_gl_MaxGeometryOutputVertices        = nullptr;
+    TVariable *mVar_gl_MaxGeometryTotalOutputComponents = nullptr;
+    TVariable *mVar_gl_MaxGeometryUniformComponents     = nullptr;
+    TVariable *mVar_gl_MaxGeometryAtomicCounters        = nullptr;
+    TVariable *mVar_gl_MaxGeometryAtomicCounterBuffers  = nullptr;
+    TVariable *mVar_gl_FragData                         = nullptr;
+    TVariable *mVar_gl_SecondaryFragDataEXT             = nullptr;
+    TVariable *mVar_gl_FragDepthEXT                     = nullptr;
+    TVariable *mVar_gl_LastFragData                     = nullptr;
+    TVariable *mVar_gl_LastFragDataNV                   = nullptr;
+    TInterfaceBlock *mVar_gl_PerVertex                  = nullptr;
+    TVariable *mVar_gl_in                               = nullptr;
+    TVariable *mVar_gl_PositionGS                       = nullptr;
+};
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_SYMBOLTABLE_AUTOGEN_H_
--- a/gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.cpp
@@ -17,19 +17,14 @@ TSymbolUniqueId::TSymbolUniqueId(TSymbol
 }
 
 TSymbolUniqueId::TSymbolUniqueId(const TSymbol &symbol) : mId(symbol.uniqueId().get())
 {
 }
 
 TSymbolUniqueId &TSymbolUniqueId::operator=(const TSymbolUniqueId &) = default;
 
-int TSymbolUniqueId::get() const
-{
-    return mId;
-}
-
 bool TSymbolUniqueId::operator==(const TSymbolUniqueId &other) const
 {
     return mId == other.mId;
 }
 
 }  // namespace sh
--- a/gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.h
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.h
@@ -15,25 +15,28 @@ namespace sh
 
 class TSymbolTable;
 class TSymbol;
 
 class TSymbolUniqueId
 {
   public:
     POOL_ALLOCATOR_NEW_DELETE();
-    explicit TSymbolUniqueId(TSymbolTable *symbolTable);
     explicit TSymbolUniqueId(const TSymbol &symbol);
     constexpr TSymbolUniqueId(const TSymbolUniqueId &) = default;
     TSymbolUniqueId &operator=(const TSymbolUniqueId &);
     bool operator==(const TSymbolUniqueId &) const;
 
-    int get() 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;
 };
 
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_SYMBOLUNIQUEID_H_
--- a/gfx/angle/checkout/src/compiler/translator/TranslatorESSL.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorESSL.cpp
@@ -1,21 +1,21 @@
 //
 // Copyright (c) 2002-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.
 //
 
 #include "compiler/translator/TranslatorESSL.h"
 
+#include "angle_gl.h"
 #include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
-#include "compiler/translator/EmulatePrecision.h"
-#include "compiler/translator/RecordConstantPrecision.h"
 #include "compiler/translator/OutputESSL.h"
-#include "angle_gl.h"
+#include "compiler/translator/tree_ops/EmulatePrecision.h"
+#include "compiler/translator/tree_ops/RecordConstantPrecision.h"
 
 namespace sh
 {
 
 TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec)
     : TCompiler(type, spec, SH_ESSL_OUTPUT)
 {
 }
--- a/gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.cpp
@@ -3,22 +3,22 @@
 // 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/EmulatePrecision.h"
 #include "compiler/translator/ExtensionGLSL.h"
 #include "compiler/translator/OutputGLSL.h"
-#include "compiler/translator/RewriteTexelFetchOffset.h"
-#include "compiler/translator/RewriteUnaryMinusOperatorFloat.h"
 #include "compiler/translator/VersionGLSL.h"
+#include "compiler/translator/tree_ops/EmulatePrecision.h"
+#include "compiler/translator/tree_ops/RewriteTexelFetchOffset.h"
+#include "compiler/translator/tree_ops/RewriteUnaryMinusOperatorFloat.h"
 
 namespace sh
 {
 
 TranslatorGLSL::TranslatorGLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
     : TCompiler(type, spec, output)
 {
 }
--- a/gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.cpp
@@ -1,36 +1,36 @@
 //
 // Copyright (c) 2002-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.
 //
 
 #include "compiler/translator/TranslatorHLSL.h"
 
-#include "compiler/translator/AddDefaultReturnStatements.h"
-#include "compiler/translator/ArrayReturnValueToOutParameter.h"
-#include "compiler/translator/BreakVariableAliasingInInnerLoops.h"
-#include "compiler/translator/EmulatePrecision.h"
-#include "compiler/translator/ExpandIntegerPowExpressions.h"
-#include "compiler/translator/IntermNodePatternMatcher.h"
 #include "compiler/translator/OutputHLSL.h"
-#include "compiler/translator/RemoveDynamicIndexing.h"
-#include "compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.h"
-#include "compiler/translator/RewriteElseBlocks.h"
-#include "compiler/translator/RewriteTexelFetchOffset.h"
-#include "compiler/translator/RewriteUnaryMinusOperatorInt.h"
-#include "compiler/translator/SeparateArrayConstructorStatements.h"
-#include "compiler/translator/SeparateArrayInitialization.h"
-#include "compiler/translator/SeparateDeclarations.h"
-#include "compiler/translator/SeparateExpressionsReturningArrays.h"
-#include "compiler/translator/SimplifyLoopConditions.h"
-#include "compiler/translator/SplitSequenceOperator.h"
-#include "compiler/translator/UnfoldShortCircuitToIf.h"
-#include "compiler/translator/WrapSwitchStatementsInBlocks.h"
+#include "compiler/translator/tree_ops/AddDefaultReturnStatements.h"
+#include "compiler/translator/tree_ops/ArrayReturnValueToOutParameter.h"
+#include "compiler/translator/tree_ops/BreakVariableAliasingInInnerLoops.h"
+#include "compiler/translator/tree_ops/EmulatePrecision.h"
+#include "compiler/translator/tree_ops/ExpandIntegerPowExpressions.h"
+#include "compiler/translator/tree_ops/PruneEmptyCases.h"
+#include "compiler/translator/tree_ops/RemoveDynamicIndexing.h"
+#include "compiler/translator/tree_ops/RewriteElseBlocks.h"
+#include "compiler/translator/tree_ops/RewriteTexelFetchOffset.h"
+#include "compiler/translator/tree_ops/RewriteUnaryMinusOperatorInt.h"
+#include "compiler/translator/tree_ops/SeparateArrayConstructorStatements.h"
+#include "compiler/translator/tree_ops/SeparateArrayInitialization.h"
+#include "compiler/translator/tree_ops/SeparateDeclarations.h"
+#include "compiler/translator/tree_ops/SeparateExpressionsReturningArrays.h"
+#include "compiler/translator/tree_ops/SimplifyLoopConditions.h"
+#include "compiler/translator/tree_ops/SplitSequenceOperator.h"
+#include "compiler/translator/tree_ops/UnfoldShortCircuitToIf.h"
+#include "compiler/translator/tree_ops/WrapSwitchStatementsInBlocks.h"
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
 
 namespace sh
 {
 
 TranslatorHLSL::TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
     : TCompiler(type, spec, output)
 {
 }
@@ -88,23 +88,20 @@ void TranslatorHLSL::translate(TIntermBl
 
     // 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.
     sh::BreakVariableAliasingInInnerLoops(root);
 
     // WrapSwitchStatementsInBlocks should be called after any AST transformations that might
-    // introduce variable declarations inside the main scope of any switch statement.
-    if (WrapSwitchStatementsInBlocks(root))
-    {
-        // The WrapSwitchStatementsInBlocks step might introduce new no-op cases to the end of
-        // switch statements, so make sure to clean up the AST.
-        RemoveNoOpCasesFromEndOfSwitchStatements(root, &getSymbolTable());
-    }
+    // 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.
+    WrapSwitchStatementsInBlocks(root);
 
     bool precisionEmulation =
         getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision;
 
     if (precisionEmulation)
     {
         EmulatePrecision emulatePrecision(&getSymbolTable());
         root->traverse(&emulatePrecision);
--- a/gfx/angle/checkout/src/compiler/translator/Types.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/Types.cpp
@@ -474,76 +474,61 @@ bool TType::canReplaceWithConstantUnion(
     return true;
 }
 
 //
 // Recursively generate mangled names.
 //
 const char *TType::buildMangledName() const
 {
-    TString mangledName;
-    if (isMatrix())
-        mangledName += 'm';
-    else if (isVector())
-        mangledName += 'v';
+    TString mangledName(1, GetSizeMangledName(primarySize, secondarySize));
 
-    const char *basicMangledName = GetBasicMangledName(type);
-    if (basicMangledName != nullptr)
+    char basicMangledName = GetBasicMangledName(type);
+    if (basicMangledName != '{')
     {
         mangledName += basicMangledName;
     }
     else
     {
         ASSERT(type == EbtStruct || type == EbtInterfaceBlock);
         switch (type)
         {
             case EbtStruct:
-                mangledName += "struct-";
+                mangledName += "{s";
                 if (mStructure->symbolType() != SymbolType::Empty)
                 {
                     mangledName += mStructure->name().data();
                 }
                 mangledName += mStructure->mangledFieldList();
+                mangledName += '}';
                 break;
             case EbtInterfaceBlock:
-                mangledName += "iblock-";
+                mangledName += "{i";
                 mangledName += mInterfaceBlock->name().data();
                 mangledName += mInterfaceBlock->mangledFieldList();
+                mangledName += '}';
                 break;
             default:
                 UNREACHABLE();
                 break;
         }
     }
 
-    if (isMatrix())
-    {
-        mangledName += static_cast<char>('0' + getCols());
-        mangledName += static_cast<char>('x');
-        mangledName += static_cast<char>('0' + getRows());
-    }
-    else
-    {
-        mangledName += static_cast<char>('0' + getNominalSize());
-    }
-
     if (mArraySizes)
     {
         for (unsigned int arraySize : *mArraySizes)
         {
             char buf[20];
             snprintf(buf, sizeof(buf), "%d", arraySize);
             mangledName += '[';
             mangledName += buf;
             mangledName += ']';
         }
     }
 
-    mangledName += ';';
-
     // 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;
 
@@ -774,21 +759,16 @@ const char *TType::getMangledName() cons
     return mMangledName;
 }
 
 void TType::realize()
 {
     getMangledName();
 }
 
-bool TType::isRealized() const
-{
-    return mMangledName != nullptr;
-}
-
 void TType::invalidateMangledName()
 {
     mMangledName = nullptr;
 }
 
 void TType::createSamplerSymbols(const ImmutableString &namePrefix,
                                  const TString &apiNamePrefix,
                                  TVector<const TVariable *> *outputSymbols,
@@ -879,17 +859,16 @@ bool TFieldListCollection::containsSampl
     return false;
 }
 
 TString TFieldListCollection::buildMangledFieldList() const
 {
     TString mangledName;
     for (const auto *field : *mFields)
     {
-        mangledName += '-';
         mangledName += field->type()->getMangledName();
     }
     return mangledName;
 }
 
 size_t TFieldListCollection::calculateObjectSize() const
 {
     size_t size = 0;
--- a/gfx/angle/checkout/src/compiler/translator/Types.h
+++ b/gfx/angle/checkout/src/compiler/translator/Types.h
@@ -224,16 +224,25 @@ class TType
     }
     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(unsigned char primarySize, unsigned char 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
@@ -314,18 +323,16 @@ class TType
                               const TString &apiNamePrefix,
                               TVector<const TVariable *> *outputSymbols,
                               TMap<const TVariable *, TString> *outputSymbolsToAPINames,
                               TSymbolTable *symbolTable) const;
 
     // Initializes all lazily-initialized members.
     void realize();
 
-    bool isRealized() const;
-
   private:
     void invalidateMangledName();
     const char *buildMangledName() const;
 
     TBasicType type;
     TPrecision precision;
     TQualifier qualifier;
     bool invariant;
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/UnfoldShortCircuitAST.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-#include "compiler/translator/UnfoldShortCircuitAST.h"
-
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/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
-
-void UnfoldShortCircuitAST(TIntermBlock *root)
-{
-    UnfoldShortCircuitASTTraverser traverser;
-    root->traverse(&traverser);
-    traverser.updateTree();
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/UnfoldShortCircuitAST.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// UnfoldShortCircuitAST is an AST traverser to replace short-circuiting
-// operations with ternary operations.
-//
-
-#ifndef COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUITAST_H_
-#define COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUITAST_H_
-
-namespace sh
-{
-
-class TIntermBlock;
-
-void UnfoldShortCircuitAST(TIntermBlock *root);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUITAST_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/UnfoldShortCircuitToIf.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// 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/UnfoldShortCircuitToIf.h"
-
-#include "compiler/translator/IntermNodePatternMatcher.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/StaticType.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));
-            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
-
-void UnfoldShortCircuitToIf(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())
-            traverser.updateTree();
-    } while (traverser.foundShortCircuit());
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/UnfoldShortCircuitToIf.h
+++ /dev/null
@@ -1,25 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-// 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_UNFOLDSHORTCIRCUIT_H_
-#define COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_
-
-namespace sh
-{
-
-class TIntermNode;
-class TSymbolTable;
-
-void UnfoldShortCircuitToIf(TIntermNode *root, TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/UseInterfaceBlockFields.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-//
-// 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/UseInterfaceBlockFields.h"
-
-#include "compiler/translator/FindMain.h"
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/SymbolTable.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 anonymous
-
-void UseInterfaceBlockFields(TIntermBlock *root,
-                             const InterfaceBlockList &blocks,
-                             const TSymbolTable &symbolTable)
-{
-    TIntermBlock *mainBody = FindMainBody(root);
-    InsertUseCode(mainBody->getSequence(), blocks, symbolTable);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/UseInterfaceBlockFields.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// 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_USEINTERFACEBLOCKFIELDS_H_
-#define COMPILER_TRANSLATOR_USEINTERFACEBLOCKFIELDS_H_
-
-#include <GLSLANG/ShaderLang.h>
-
-namespace sh
-{
-
-class TIntermBlock;
-class TSymbolTable;
-
-using InterfaceBlockList = std::vector<sh::InterfaceBlock>;
-
-void UseInterfaceBlockFields(TIntermBlock *root,
-                             const InterfaceBlockList &blocks,
-                             const TSymbolTable &symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_USEINTERFACEBLOCKFIELDS_H_
--- a/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.cpp
@@ -10,16 +10,43 @@
 #include "compiler/translator/UtilsHLSL.h"
 #include "compiler/translator/IntermNode.h"
 #include "compiler/translator/StructureHLSL.h"
 #include "compiler/translator/SymbolTable.h"
 
 namespace sh
 {
 
+namespace
+{
+
+void DisambiguateFunctionNameForParameterType(const TType &paramType,
+                                              TString *disambiguatingStringOut)
+{
+    // 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.
+    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.
+        *disambiguatingStringOut += "_" + TypeString(paramType);
+    }
+    else 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);
+        *disambiguatingStringOut += "_" + TypeString(paramType);
+    }
+}
+
+}  // anonymous namespace
+
 const char *SamplerString(const TBasicType type)
 {
     if (IsShadowSampler(type))
     {
         return "SamplerComparisonState";
     }
     else
     {
@@ -797,18 +824,20 @@ TString Decorate(const ImmutableString &
         return "_" + TString(string.data());
     }
 
     return TString(string.data());
 }
 
 TString DecorateVariableIfNeeded(const TVariable &variable)
 {
-    if (variable.symbolType() == SymbolType::AngleInternal)
+    if (variable.symbolType() == SymbolType::AngleInternal ||
+        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());
     }
     else
     {
@@ -1020,36 +1049,33 @@ const char *QualifierString(TQualifier q
             return "const";
         default:
             UNREACHABLE();
     }
 
     return "";
 }
 
-TString DisambiguateFunctionName(const TIntermSequence *parameters)
+TString DisambiguateFunctionName(const TFunction *func)
 {
     TString disambiguatingString;
-    for (auto parameter : *parameters)
+    size_t paramCount = func->getParamCount();
+    for (size_t i = 0; i < paramCount; ++i)
     {
-        const TType &paramType = parameter->getAsTyped()->getType();
-        // 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.
-        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.
-            disambiguatingString += "_" + TypeString(paramType);
-        }
-        else 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);
-            disambiguatingString += "_" + TypeString(paramType);
-        }
+        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
--- a/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.h
+++ b/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.h
@@ -14,16 +14,18 @@
 #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,
@@ -118,12 +120,13 @@ TString TypeString(const TType &type);
 TString StructNameString(const TStructure &structure);
 TString QualifiedStructNameString(const TStructure &structure,
                                   bool useHLSLRowMajorPacking,
                                   bool useStd140Packing);
 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 TIntermSequence *parameters);
+TString DisambiguateFunctionName(const TFunction *func);
+TString DisambiguateFunctionName(const TIntermSequence *args);
 }
 
 #endif  // COMPILER_TRANSLATOR_UTILSHLSL_H_
--- a/gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.cpp
@@ -1,36 +1,38 @@
 //
 // Copyright (c) 2002-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.
 //
 
 #include "compiler/translator/ValidateGlobalInitializer.h"
 
-#include "compiler/translator/IntermTraverse.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
 
 namespace sh
 {
 
 namespace
 {
 
+const int kMaxAllowedTraversalDepth = 256;
+
 class ValidateGlobalInitializerTraverser : public TIntermTraverser
 {
   public:
     ValidateGlobalInitializerTraverser(int shaderVersion);
 
     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; }
+    bool isValid() const { return mIsValid && mMaxDepth < mMaxAllowedDepth; }
     bool issueWarning() const { return mIssueWarning; }
 
   private:
     int mShaderVersion;
     bool mIsValid;
     bool mIssueWarning;
 };
 
@@ -112,21 +114,22 @@ bool ValidateGlobalInitializerTraverser:
     if (node->isAssignment())
     {
         mIsValid = false;
     }
     return true;
 }
 
 ValidateGlobalInitializerTraverser::ValidateGlobalInitializerTraverser(int shaderVersion)
-    : TIntermTraverser(true, false, false),
+    : TIntermTraverser(true, false, false, nullptr),
       mShaderVersion(shaderVersion),
       mIsValid(true),
       mIssueWarning(false)
 {
+    setMaxAllowedDepth(kMaxAllowedTraversalDepth);
 }
 
 }  // namespace
 
 bool ValidateGlobalInitializer(TIntermTyped *initializer, int shaderVersion, bool *warning)
 {
     ValidateGlobalInitializerTraverser validate(shaderVersion);
     initializer->traverse(&validate);
--- a/gfx/angle/checkout/src/compiler/translator/ValidateLimitations.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateLimitations.cpp
@@ -3,18 +3,18 @@
 // 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/IntermTraverse.h"
 #include "compiler/translator/ParseContext.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
 
 namespace sh
 {
 
 namespace
 {
 
 int GetLoopSymbolId(TIntermLoop *loop)
--- a/gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.cpp
@@ -3,27 +3,28 @@
 // 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()->getSequence()->size() > maxParameters)
+            definition->getFunctionPrototype()->getFunction()->getParamCount() > maxParameters)
         {
             return false;
         }
     }
     return true;
 }
 
 }  // namespace sh
--- a/gfx/angle/checkout/src/compiler/translator/ValidateOutputs.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateOutputs.cpp
@@ -7,18 +7,18 @@
 // 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/IntermTraverse.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)
--- a/gfx/angle/checkout/src/compiler/translator/ValidateSwitch.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateSwitch.cpp
@@ -2,94 +2,93 @@
 // Copyright (c) 2002-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.
 //
 
 #include "compiler/translator/ValidateSwitch.h"
 
 #include "compiler/translator/Diagnostics.h"
-#include "compiler/translator/IntermTraverse.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,
-                         int shaderVersion,
                          TDiagnostics *diagnostics,
                          TIntermBlock *statementList,
                          const TSourceLoc &loc);
 
     void visitSymbol(TIntermSymbol *) override;
     void visitConstantUnion(TIntermConstantUnion *) override;
     bool visitDeclaration(Visit, TIntermDeclaration *) override;
-    bool visitBlock(Visit, TIntermBlock *) 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, int shaderVersion, TDiagnostics *context);
+    ValidateSwitch(TBasicType switchType, TDiagnostics *context);
 
     bool validateInternal(const TSourceLoc &loc);
 
     TBasicType mSwitchType;
-    int mShaderVersion;
     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,
-                              int shaderVersion,
                               TDiagnostics *diagnostics,
                               TIntermBlock *statementList,
                               const TSourceLoc &loc)
 {
-    ValidateSwitch validate(switchType, shaderVersion, diagnostics);
+    ValidateSwitch validate(switchType, diagnostics);
     ASSERT(statementList);
     statementList->traverse(&validate);
     return validate.validateInternal(loc);
 }
 
-ValidateSwitch::ValidateSwitch(TBasicType switchType, int shaderVersion, TDiagnostics *diagnostics)
-    : TIntermTraverser(true, false, true),
+ValidateSwitch::ValidateSwitch(TBasicType switchType, TDiagnostics *diagnostics)
+    : TIntermTraverser(true, false, true, nullptr),
       mSwitchType(switchType),
-      mShaderVersion(shaderVersion),
       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;
 }
@@ -106,23 +105,27 @@ void ValidateSwitch::visitConstantUnion(
 bool ValidateSwitch::visitDeclaration(Visit, TIntermDeclaration *)
 {
     if (!mFirstCaseFound)
         mStatementBeforeCase = true;
     mLastStatementWasCase    = false;
     return true;
 }
 
-bool ValidateSwitch::visitBlock(Visit, TIntermBlock *)
+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;
@@ -276,44 +279,37 @@ bool ValidateSwitch::visitBranch(Visit, 
 }
 
 bool ValidateSwitch::validateInternal(const TSourceLoc &loc)
 {
     if (mStatementBeforeCase)
     {
         mDiagnostics->error(loc, "statement before the first label", "switch");
     }
-    bool lastStatementWasCaseError = false;
     if (mLastStatementWasCase)
     {
-        if (mShaderVersion == 300)
-        {
-            lastStatementWasCaseError = true;
-            // This error has been proposed to be made optional in GLSL ES 3.00, but dEQP tests
-            // still require it.
-            mDiagnostics->error(
-                loc, "no statement between the last label and the end of the switch statement",
-                "switch");
-        }
-        else
-        {
-            // The error has been removed from GLSL ES 3.10.
-            mDiagnostics->warning(
-                loc, "no statement between the last label and the end of the switch statement",
-                "switch");
-        }
+        // 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");
     }
-    return !mStatementBeforeCase && !lastStatementWasCaseError && !mCaseInsideControlFlow &&
-           !mCaseTypeMismatch && mDefaultCount <= 1 && !mDuplicateCases;
+    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,
-                                 int shaderVersion,
                                  TDiagnostics *diagnostics,
                                  TIntermBlock *statementList,
                                  const TSourceLoc &loc)
 {
-    return ValidateSwitch::validate(switchType, shaderVersion, diagnostics, statementList, loc);
+    return ValidateSwitch::validate(switchType, diagnostics, statementList, loc);
 }
 
 }  // namespace sh
--- a/gfx/angle/checkout/src/compiler/translator/ValidateSwitch.h
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateSwitch.h
@@ -13,16 +13,15 @@
 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,
-                                 int shaderVersion,
                                  TDiagnostics *diagnostics,
                                  TIntermBlock *statementList,
                                  const TSourceLoc &loc);
 
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_VALIDATESWITCH_H_
--- a/gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.cpp
@@ -5,18 +5,18 @@
 //
 // The ValidateVaryingLocations function checks if there exists location conflicts on shader
 // varyings.
 //
 
 #include "ValidateVaryingLocations.h"
 
 #include "compiler/translator/Diagnostics.h"
-#include "compiler/translator/IntermTraverse.h"
 #include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
 #include "compiler/translator/util.h"
 
 namespace sh
 {
 
 namespace
 {
 
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/VectorizeVectorScalarArithmetic.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright (c) 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.
-//
-// VectorizeVectorScalarArithmetic.cpp: Turn some arithmetic operations that operate on a float
-// vector-scalar pair into vector-vector operations. This is done recursively. Some scalar binary
-// operations inside vector constructors are also turned into vector operations.
-//
-// This is targeted to work around a bug in NVIDIA OpenGL drivers that was reproducible on NVIDIA
-// driver version 387.92. It works around the most common occurrences of the bug.
-
-#include "compiler/translator/VectorizeVectorScalarArithmetic.h"
-
-#include <set>
-
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class VectorizeVectorScalarArithmeticTraverser : public TIntermTraverser
-{
-  public:
-    VectorizeVectorScalarArithmeticTraverser(TSymbolTable *symbolTable)
-        : TIntermTraverser(true, false, false, symbolTable), mReplaced(false)
-    {
-    }
-
-    bool didReplaceScalarsWithVectors() { return mReplaced; }
-    void nextIteration()
-    {
-        mReplaced = false;
-        mModifiedBlocks.clear();
-    }
-
-  protected:
-    bool visitBinary(Visit visit, TIntermBinary *node) override;
-    bool visitAggregate(Visit visit, TIntermAggregate *node) override;
-
-  private:
-    // These helpers should only be called from visitAggregate when visiting a constructor.
-    // argBinary is the only argument of the constructor.
-    void replaceMathInsideConstructor(TIntermAggregate *node, TIntermBinary *argBinary);
-    void replaceAssignInsideConstructor(const TIntermAggregate *node,
-                                        const TIntermBinary *argBinary);
-
-    static TIntermTyped *Vectorize(TIntermTyped *node,
-                                   TType vectorType,
-                                   TIntermTraverser::OriginalNode *originalNodeFate);
-
-    bool mReplaced;
-    std::set<const TIntermBlock *> mModifiedBlocks;
-};
-
-TIntermTyped *VectorizeVectorScalarArithmeticTraverser::Vectorize(
-    TIntermTyped *node,
-    TType vectorType,
-    TIntermTraverser::OriginalNode *originalNodeFate)
-{
-    ASSERT(node->isScalar());
-    vectorType.setQualifier(EvqTemporary);
-    TIntermSequence vectorConstructorArgs;
-    vectorConstructorArgs.push_back(node);
-    TIntermAggregate *vectorized =
-        TIntermAggregate::CreateConstructor(vectorType, &vectorConstructorArgs);
-    TIntermTyped *vectorizedFolded = vectorized->fold(nullptr);
-    if (originalNodeFate != nullptr)
-    {
-        if (vectorizedFolded != vectorized)
-        {
-            *originalNodeFate = OriginalNode::IS_DROPPED;
-        }
-        else
-        {
-            *originalNodeFate = OriginalNode::BECOMES_CHILD;
-        }
-    }
-    return vectorizedFolded;
-}
-
-bool VectorizeVectorScalarArithmeticTraverser::visitBinary(Visit /*visit*/, TIntermBinary *node)
-{
-    TIntermTyped *left  = node->getLeft();
-    TIntermTyped *right = node->getRight();
-    ASSERT(left);
-    ASSERT(right);
-    switch (node->getOp())
-    {
-        case EOpAdd:
-        case EOpAddAssign:
-            // Only these specific ops are necessary to turn into vector ops.
-            break;
-        default:
-            return true;
-    }
-    if (node->getBasicType() != EbtFloat)
-    {
-        // Only float ops have reproduced the bug.
-        return true;
-    }
-    if (left->isScalar() && right->isVector())
-    {
-        ASSERT(!node->isAssignment());
-        ASSERT(!right->isArray());
-        OriginalNode originalNodeFate;
-        TIntermTyped *leftVectorized = Vectorize(left, right->getType(), &originalNodeFate);
-        queueReplacementWithParent(node, left, leftVectorized, originalNodeFate);
-        mReplaced = true;
-        // Don't replace more nodes in the same subtree on this traversal. However, nodes elsewhere
-        // in the tree may still be replaced.
-        return false;
-    }
-    else if (left->isVector() && right->isScalar())
-    {
-        OriginalNode originalNodeFate;
-        TIntermTyped *rightVectorized = Vectorize(right, left->getType(), &originalNodeFate);
-        queueReplacementWithParent(node, right, rightVectorized, originalNodeFate);
-        mReplaced = true;
-        // Don't replace more nodes in the same subtree on this traversal. However, nodes elsewhere
-        // in the tree may still be replaced.
-        return false;
-    }
-    return true;
-}
-
-void VectorizeVectorScalarArithmeticTraverser::replaceMathInsideConstructor(
-    TIntermAggregate *node,
-    TIntermBinary *argBinary)
-{
-    // Turn:
-    //   a * b
-    // into:
-    //   gvec(a) * gvec(b)
-
-    TIntermTyped *left  = argBinary->getLeft();
-    TIntermTyped *right = argBinary->getRight();
-    ASSERT(left->isScalar() && right->isScalar());
-
-    TType leftVectorizedType = left->getType();
-    leftVectorizedType.setPrimarySize(static_cast<unsigned char>(node->getType().getNominalSize()));
-    TIntermTyped *leftVectorized = Vectorize(left, leftVectorizedType, nullptr);
-    TType rightVectorizedType    = right->getType();
-    rightVectorizedType.setPrimarySize(
-        static_cast<unsigned char>(node->getType().getNominalSize()));
-    TIntermTyped *rightVectorized = Vectorize(right, rightVectorizedType, nullptr);
-
-    TIntermBinary *newArg = new TIntermBinary(argBinary->getOp(), leftVectorized, rightVectorized);
-    queueReplacementWithParent(node, argBinary, newArg, OriginalNode::IS_DROPPED);
-}
-
-void VectorizeVectorScalarArithmeticTraverser::replaceAssignInsideConstructor(
-    const TIntermAggregate *node,
-    const TIntermBinary *argBinary)
-{
-    // Turn:
-    //   gvec(a *= b);
-    // into:
-    //   // This is inserted into the parent block:
-    //   gvec s0 = gvec(a);
-    //
-    //   // This goes where the gvec constructor used to be:
-    //   ((s0 *= b, a = s0.x), s0);
-
-    TIntermTyped *left  = argBinary->getLeft();
-    TIntermTyped *right = argBinary->getRight();
-    ASSERT(left->isScalar() && right->isScalar());
-    ASSERT(!left->hasSideEffects());
-
-    TType vecType = node->getType();
-    vecType.setQualifier(EvqTemporary);
-
-    // gvec s0 = gvec(a);
-    // s0 is called "tempAssignmentTarget" below.
-    TIntermTyped *tempAssignmentTargetInitializer = Vectorize(left->deepCopy(), vecType, nullptr);
-    TIntermDeclaration *tempAssignmentTargetDeclaration = nullptr;
-    TVariable *tempAssignmentTarget =
-        DeclareTempVariable(mSymbolTable, tempAssignmentTargetInitializer, EvqTemporary,
-                            &tempAssignmentTargetDeclaration);
-
-    // s0 *= b
-    TOperator compoundAssignmentOp = argBinary->getOp();
-    if (compoundAssignmentOp == EOpMulAssign)
-    {
-        compoundAssignmentOp = EOpVectorTimesScalarAssign;
-    }
-    TIntermBinary *replacementCompoundAssignment = new TIntermBinary(
-        compoundAssignmentOp, CreateTempSymbolNode(tempAssignmentTarget), right->deepCopy());
-
-    // s0.x
-    TVector<int> swizzleXOffset;
-    swizzleXOffset.push_back(0);
-    TIntermSwizzle *tempAssignmentTargetX =
-        new TIntermSwizzle(CreateTempSymbolNode(tempAssignmentTarget), swizzleXOffset);
-    // a = s0.x
-    TIntermBinary *replacementAssignBackToTarget =
-        new TIntermBinary(EOpAssign, left->deepCopy(), tempAssignmentTargetX);
-
-    // s0 *= b, a = s0.x
-    TIntermBinary *replacementSequenceLeft =
-        new TIntermBinary(EOpComma, replacementCompoundAssignment, replacementAssignBackToTarget);
-    // (s0 *= b, a = s0.x), s0
-    // Note that the created comma node is not const qualified in any case, so we can always pass
-    // shader version 300 here.
-    TIntermBinary *replacementSequence = TIntermBinary::CreateComma(
-        replacementSequenceLeft, CreateTempSymbolNode(tempAssignmentTarget), 300);
-
-    insertStatementInParentBlock(tempAssignmentTargetDeclaration);
-    queueReplacement(replacementSequence, OriginalNode::IS_DROPPED);
-}
-
-bool VectorizeVectorScalarArithmeticTraverser::visitAggregate(Visit /*visit*/,
-                                                              TIntermAggregate *node)
-{
-    // Transform scalar binary expressions inside vector constructors.
-    if (!node->isConstructor() || !node->isVector() || node->getSequence()->size() != 1)
-    {
-        return true;
-    }
-    TIntermTyped *argument = node->getSequence()->back()->getAsTyped();
-    ASSERT(argument);
-    if (!argument->isScalar() || argument->getBasicType() != EbtFloat)
-    {
-        return true;
-    }
-    TIntermBinary *argBinary = argument->getAsBinaryNode();
-    if (!argBinary)
-    {
-        return true;
-    }
-
-    // Only specific ops are necessary to change.
-    switch (argBinary->getOp())
-    {
-        case EOpMul:
-        case EOpDiv:
-        {
-            replaceMathInsideConstructor(node, argBinary);
-            mReplaced = true;
-            // Don't replace more nodes in the same subtree on this traversal. However, nodes
-            // elsewhere in the tree may still be replaced.
-            return false;
-        }
-        case EOpMulAssign:
-        case EOpDivAssign:
-        {
-            // The case where the left side has side effects is too complicated to deal with, so we
-            // leave that be.
-            if (!argBinary->getLeft()->hasSideEffects())
-            {
-                const TIntermBlock *parentBlock = getParentBlock();
-                // We can't do more than one insertion to the same block on the same traversal.
-                if (mModifiedBlocks.find(parentBlock) == mModifiedBlocks.end())
-                {
-                    replaceAssignInsideConstructor(node, argBinary);
-                    mModifiedBlocks.insert(parentBlock);
-                    mReplaced = true;
-                    // Don't replace more nodes in the same subtree on this traversal.
-                    // However, nodes elsewhere in the tree may still be replaced.
-                    return false;
-                }
-            }
-            break;
-        }
-        default:
-            return true;
-    }
-    return true;
-}
-
-}  // anonymous namespace
-
-void VectorizeVectorScalarArithmetic(TIntermBlock *root, TSymbolTable *symbolTable)
-{
-    VectorizeVectorScalarArithmeticTraverser traverser(symbolTable);
-    do
-    {
-        traverser.nextIteration();
-        root->traverse(&traverser);
-        traverser.updateTree();
-    } while (traverser.didReplaceScalarsWithVectors());
-}
-
-}  // namespace sh
\ No newline at end of file
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/VectorizeVectorScalarArithmetic.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 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.
-//
-// VectorizeVectorScalarArithmetic.h: Turn some arithmetic operations that operate on a float
-// vector-scalar pair into vector-vector operations. This is done recursively. Some scalar binary
-// operations inside vector constructors are also turned into vector operations.
-//
-// This is targeted to work around a bug in NVIDIA OpenGL drivers that was reproducible on NVIDIA
-// driver version 387.92. It works around the most common occurrences of the bug.
-
-#ifndef COMPILER_TRANSLATOR_VECTORIZEVECTORSCALARARITHMETIC_H_
-#define COMPILER_TRANSLATOR_VECTORIZEVECTORSCALARARITHMETIC_H_
-
-namespace sh
-{
-
-class TIntermBlock;
-class TSymbolTable;
-
-void VectorizeVectorScalarArithmetic(TIntermBlock *root, TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_VECTORIZEVECTORSCALARARITHMETIC_H_
\ No newline at end of file
--- a/gfx/angle/checkout/src/compiler/translator/VersionGLSL.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/VersionGLSL.cpp
@@ -100,34 +100,33 @@ bool TVersionGLSL::visitDeclaration(Visi
 }
 
 bool TVersionGLSL::visitInvariantDeclaration(Visit, TIntermInvariantDeclaration *node)
 {
     ensureVersionIsAtLeast(GLSL_VERSION_120);
     return true;
 }
 
-bool TVersionGLSL::visitFunctionPrototype(Visit, TIntermFunctionPrototype *node)
+void TVersionGLSL::visitFunctionPrototype(TIntermFunctionPrototype *node)
 {
-    const TIntermSequence &params = *(node->getSequence());
-    for (TIntermSequence::const_iterator iter = params.begin(); iter != params.end(); ++iter)
+    size_t paramCount = node->getFunction()->getParamCount();
+    for (size_t i = 0; i < paramCount; ++i)
     {
-        const TIntermTyped *param = (*iter)->getAsTyped();
-        if (param->isArray())
+        const TVariable *param = node->getFunction()->getParam(i);
+        const TType &type      = param->getType();
+        if (type.isArray())
         {
-            TQualifier qualifier = param->getQualifier();
+            TQualifier qualifier = type.getQualifier();
             if ((qualifier == EvqOut) || (qualifier == EvqInOut))
             {
                 ensureVersionIsAtLeast(GLSL_VERSION_120);
                 break;
             }
         }
     }
-    // Fully processed. No need to visit children.
-    return false;
 }
 
 bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node)
 {
     if (node->getOp() == EOpConstruct && node->getType().isMatrix())
     {
         const TIntermSequence &sequence = *(node->getSequence());
         if (sequence.size() == 1)
--- a/gfx/angle/checkout/src/compiler/translator/VersionGLSL.h
+++ b/gfx/angle/checkout/src/compiler/translator/VersionGLSL.h
@@ -2,17 +2,17 @@
 // Copyright (c) 2002-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.
 //
 
 #ifndef COMPILER_TRANSLATOR_VERSIONGLSL_H_
 #define COMPILER_TRANSLATOR_VERSIONGLSL_H_
 
-#include "compiler/translator/IntermTraverse.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;
@@ -57,17 +57,17 @@ class TVersionGLSL : public TIntermTrave
     //   - 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 visitInvariantDeclaration(Visit, TIntermInvariantDeclaration *node) override;
-    bool visitFunctionPrototype(Visit, TIntermFunctionPrototype *node) override;
+    void visitFunctionPrototype(TIntermFunctionPrototype *node) override;
     bool visitDeclaration(Visit, TIntermDeclaration *node) override;
 
   private:
     void ensureVersionIsAtLeast(int version);
 
     int mVersion;
 };
 
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/WrapSwitchStatementsInBlocks.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-//
-// Copyright (c) 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/WrapSwitchStatementsInBlocks.h"
-
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/IntermTraverse.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class WrapSwitchStatementsInBlocksTraverser : public TIntermTraverser
-{
-  public:
-    WrapSwitchStatementsInBlocksTraverser() : TIntermTraverser(true, false, false), mDidWrap(false)
-    {
-    }
-
-    bool visitSwitch(Visit visit, TIntermSwitch *node) override;
-
-    bool didWrap() const { return mDidWrap; }
-
-  private:
-    bool mDidWrap;
-};
-
-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.push_back(NodeReplaceWithMultipleEntry(
-                node->getStatementList(), declaration, emptyReplacement));
-
-            declarationInBlock->appendDeclarator(declaratorAsSymbol->deepCopy());
-        }
-        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);
-    mDidWrap = true;
-
-    // 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(TIntermBlock *root)
-{
-    WrapSwitchStatementsInBlocksTraverser traverser;
-    root->traverse(&traverser);
-    traverser.updateTree();
-    return traverser.didWrap();
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/WrapSwitchStatementsInBlocks.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//
-// Copyright (c) 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_WRAPSWITCHSTATEMENTSINBLOCKS_H_
-#define COMPILER_TRANSLATOR_WRAPSWITCHSTATEMENTSINBLOCKS_H_
-
-namespace sh
-{
-
-class TIntermBlock;
-
-// Wrap switch statements in the AST into blocks when needed. Returns true if the AST was changed.
-bool WrapSwitchStatementsInBlocks(TIntermBlock *root);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_WRAPSWITCHSTATEMENTSINBLOCKS_H_
--- 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
@@ -1,391 +1,393 @@
 // 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.
+// 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.
 //
 // 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_autogen.h"
 
 namespace sh
 {
 
 namespace
 {
 
 struct FunctionPair
 {
-    constexpr FunctionPair(const MiniFunctionId &idIn, const char *bodyIn) : id(idIn), body(bodyIn)
+    constexpr FunctionPair(const TSymbolUniqueId &idIn, const char *bodyIn)
+        : id(idIn.get()), body(bodyIn)
     {
     }
 
-    MiniFunctionId id;
+    int id;
     const char *body;
 };
 
 constexpr FunctionPair g_hlslFunctions[] = {
-    {{EOpMod, ParamType::Float1, ParamType::Float1},
+    {BuiltInId::mod_Float1_Float1,
      "float mod_emu(float x, float y)\n"
      "{\n"
      "    return x - y * floor(x / y);\n"
      "}\n"},
-    {{EOpMod, ParamType::Float2, ParamType::Float2},
+    {BuiltInId::mod_Float2_Float2,
      "float2 mod_emu(float2 x, float2 y)\n"
      "{\n"
      "    return x - y * floor(x / y);\n"
      "}\n"},
-    {{EOpMod, ParamType::Float2, ParamType::Float1},
+    {BuiltInId::mod_Float2_Float1,
      "float2 mod_emu(float2 x, float y)\n"
      "{\n"
      "    return x - y * floor(x / y);\n"
      "}\n"},
-    {{EOpMod, ParamType::Float3, ParamType::Float3},
+    {BuiltInId::mod_Float3_Float3,
      "float3 mod_emu(float3 x, float3 y)\n"
      "{\n"
      "    return x - y * floor(x / y);\n"
      "}\n"},
-    {{EOpMod, ParamType::Float3, ParamType::Float1},
+    {BuiltInId::mod_Float3_Float1,
      "float3 mod_emu(float3 x, float y)\n"
      "{\n"
      "    return x - y * floor(x / y);\n"
      "}\n"},
-    {{EOpMod, ParamType::Float4, ParamType::Float4},
+    {BuiltInId::mod_Float4_Float4,
      "float4 mod_emu(float4 x, float4 y)\n"
      "{\n"
      "    return x - y * floor(x / y);\n"
      "}\n"},
-    {{EOpMod, ParamType::Float4, ParamType::Float1},
+    {BuiltInId::mod_Float4_Float1,
      "float4 mod_emu(float4 x, float y)\n"
      "{\n"
      "    return x - y * floor(x / y);\n"
      "}\n"},
-    {{EOpFrexp, ParamType::Float1, ParamType::Int1},
+    {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"},
-    {{EOpFrexp, ParamType::Float2, ParamType::Int2},
+    {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"},
-    {{EOpFrexp, ParamType::Float3, ParamType::Int3},
+    {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"},
-    {{EOpFrexp, ParamType::Float4, ParamType::Int4},
+    {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"},
-    {{EOpLdexp, ParamType::Float1, ParamType::Int1},
+    {BuiltInId::ldexp_Float1_Int1,
      "float ldexp_emu(float x, int exp)\n"
      "{\n"
      "    return ldexp(x, float(exp));\n"
      "}\n"},
-    {{EOpLdexp, ParamType::Float2, ParamType::Int2},
+    {BuiltInId::ldexp_Float2_Int2,
      "float2 ldexp_emu(float2 x, int2 exp)\n"
      "{\n"
      "    return ldexp(x, float2(exp));\n"
      "}\n"},
-    {{EOpLdexp, ParamType::Float3, ParamType::Int3},
+    {BuiltInId::ldexp_Float3_Int3,
      "float3 ldexp_emu(float3 x, int3 exp)\n"
      "{\n"
      "    return ldexp(x, float3(exp));\n"
      "}\n"},
-    {{EOpLdexp, ParamType::Float4, ParamType::Int4},
+    {BuiltInId::ldexp_Float4_Int4,
      "float4 ldexp_emu(float4 x, int4 exp)\n"
      "{\n"
      "    return ldexp(x, float4(exp));\n"
      "}\n"},
-    {{EOpFaceforward, ParamType::Float1, ParamType::Float1, ParamType::Float1},
+    {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"},
-    {{EOpFaceforward, ParamType::Float2, ParamType::Float2, ParamType::Float2},
+    {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"},
-    {{EOpFaceforward, ParamType::Float3, ParamType::Float3, ParamType::Float3},
+    {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"},
-    {{EOpFaceforward, ParamType::Float4, ParamType::Float4, ParamType::Float4},
+    {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"},
-    {{EOpAtan, ParamType::Float1, ParamType::Float1},
+    {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"},
-    {{EOpAtan, ParamType::Float2, ParamType::Float2},
+    {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"},
-    {{EOpAtan, ParamType::Float3, ParamType::Float3},
+    {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"},
-    {{EOpAtan, ParamType::Float4, ParamType::Float4},
+    {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"},
-    {{EOpAsinh, ParamType::Float1},
+    {BuiltInId::asinh_Float1,
      "float asinh_emu(in float x)\n"
      "{\n"
      "    return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
      "}\n"},
-    {{EOpAsinh, ParamType::Float2},
+    {BuiltInId::asinh_Float2,
      "float2 asinh_emu(in float2 x)\n"
      "{\n"
      "    return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
      "}\n"},
-    {{EOpAsinh, ParamType::Float3},
+    {BuiltInId::asinh_Float3,
      "float3 asinh_emu(in float3 x)\n"
      "{\n"
      "    return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
      "}\n"},
-    {{EOpAsinh, ParamType::Float4},
+    {BuiltInId::asinh_Float4,
      "float4 asinh_emu(in float4 x)\n"
      "{\n"
      "    return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
      "}\n"},
-    {{EOpAcosh, ParamType::Float1},
+    {BuiltInId::acosh_Float1,
      "float acosh_emu(in float x)\n"
      "{\n"
      "    return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
      "}\n"},
-    {{EOpAcosh, ParamType::Float2},
+    {BuiltInId::acosh_Float2,
      "float2 acosh_emu(in float2 x)\n"
      "{\n"
      "    return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
      "}\n"},
-    {{EOpAcosh, ParamType::Float3},
+    {BuiltInId::acosh_Float3,
      "float3 acosh_emu(in float3 x)\n"
      "{\n"
      "    return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
      "}\n"},
-    {{EOpAcosh, ParamType::Float4},
+    {BuiltInId::acosh_Float4,
      "float4 acosh_emu(in float4 x)\n"
      "{\n"
      "    return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
      "}\n"},
-    {{EOpAtanh, ParamType::Float1},
+    {BuiltInId::atanh_Float1,
      "float atanh_emu(in float x)\n"
      "{\n"
      "    return 0.5 * log((1.0 + x) / (1.0 - x));\n"
      "}\n"},
-    {{EOpAtanh, ParamType::Float2},
+    {BuiltInId::atanh_Float2,
      "float2 atanh_emu(in float2 x)\n"
      "{\n"
      "    return 0.5 * log((1.0 + x) / (1.0 - x));\n"
      "}\n"},
-    {{EOpAtanh, ParamType::Float3},
+    {BuiltInId::atanh_Float3,
      "float3 atanh_emu(in float3 x)\n"
      "{\n"
      "    return 0.5 * log((1.0 + x) / (1.0 - x));\n"
      "}\n"},
-    {{EOpAtanh, ParamType::Float4},
+    {BuiltInId::atanh_Float4,
      "float4 atanh_emu(in float4 x)\n"
      "{\n"
      "    return 0.5 * log((1.0 + x) / (1.0 - x));\n"
      "}\n"},
-    {{EOpRoundEven, ParamType::Float1},
+    {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"},
-    {{EOpRoundEven, ParamType::Float2},
+    {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"},
-    {{EOpRoundEven, ParamType::Float3},
+    {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"},
-    {{EOpRoundEven, ParamType::Float4},
+    {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"},
-    {{EOpPackSnorm2x16, ParamType::Float2},
+    {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"},
-    {{EOpPackUnorm2x16, ParamType::Float2},
+    {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"},
-    {{EOpPackHalf2x16, ParamType::Float2},
+    {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"},
-    {{EOpUnpackSnorm2x16, ParamType::Uint1},
+    {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"},
-    {{EOpUnpackUnorm2x16, ParamType::Uint1},
+    {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"},
-    {{EOpUnpackHalf2x16, ParamType::Uint1},
+    {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"},
-    {{EOpPackSnorm4x8, ParamType::Float4},
+    {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"},
-    {{EOpPackUnorm4x8, ParamType::Float4},
+    {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"},
-    {{EOpUnpackSnorm4x8, ParamType::Uint1},
+    {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"},
-    {{EOpUnpackUnorm4x8, ParamType::Uint1},
+    {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"
@@ -397,95 +399,95 @@ constexpr FunctionPair g_hlslFunctions[]
     // (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.
-    {{EOpOuterProduct, ParamType::Float2, ParamType::Float2},
+    {BuiltInId::outerProduct_Float2_Float2,
      "float2x2 outerProduct_emu(in float2 c, in float2 r)\n"
      "{\n"
      "    return mul(float2x1(r), float1x2(c));\n"
      "}\n"},
-    {{EOpOuterProduct, ParamType::Float3, ParamType::Float3},
+    {BuiltInId::outerProduct_Float3_Float3,
      "float3x3 outerProduct_emu(in float3 c, in float3 r)\n"
      "{\n"
      "    return mul(float3x1(r), float1x3(c));\n"
      "}\n"},
-    {{EOpOuterProduct, ParamType::Float4, ParamType::Float4},
+    {BuiltInId::outerProduct_Float4_Float4,
      "float4x4 outerProduct_emu(in float4 c, in float4 r)\n"
      "{\n"
      "    return mul(float4x1(r), float1x4(c));\n"
      "}\n"},
-    {{EOpOuterProduct, ParamType::Float3, ParamType::Float2},
+    {BuiltInId::outerProduct_Float3_Float2,
      "float2x3 outerProduct_emu(in float3 c, in float2 r)\n"
      "{\n"
      "    return mul(float2x1(r), float1x3(c));\n"
      "}\n"},
-    {{EOpOuterProduct, ParamType::Float2, ParamType::Float3},
+    {BuiltInId::outerProduct_Float2_Float3,
      "float3x2 outerProduct_emu(in float2 c, in float3 r)\n"
      "{\n"
      "    return mul(float3x1(r), float1x2(c));\n"
      "}\n"},
-    {{EOpOuterProduct, ParamType::Float4, ParamType::Float2},
+    {BuiltInId::outerProduct_Float4_Float2,
      "float2x4 outerProduct_emu(in float4 c, in float2 r)\n"
      "{\n"
      "    return mul(float2x1(r), float1x4(c));\n"
      "}\n"},
-    {{EOpOuterProduct, ParamType::Float2, ParamType::Float4},
+    {BuiltInId::outerProduct_Float2_Float4,
      "float4x2 outerProduct_emu(in float2 c, in float4 r)\n"
      "{\n"
      "    return mul(float4x1(r), float1x2(c));\n"
      "}\n"},
-    {{EOpOuterProduct, ParamType::Float4, ParamType::Float3},
+    {BuiltInId::outerProduct_Float4_Float3,
      "float3x4 outerProduct_emu(in float4 c, in float3 r)\n"
      "{\n"
      "    return mul(float3x1(r), float1x4(c));\n"
      "}\n"},
-    {{EOpOuterProduct, ParamType::Float3, ParamType::Float4},
+    {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.
-    {{EOpInverse, ParamType::Mat2},
+    {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.
-    {{EOpInverse, ParamType::Mat3},
+    {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"},
-    {{EOpInverse, ParamType::Mat4},
+    {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"
@@ -551,330 +553,330 @@ constexpr FunctionPair g_hlslFunctions[]
      "     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.
-    {{EOpMix, ParamType::Float1, ParamType::Float1, ParamType::Bool1},
+    {BuiltInId::mix_Float1_Float1_Bool1,
      "float mix_emu(float x, float y, bool a)\n"
      "{\n"
      "    return a ? y : x;\n"
      "}\n"},
-    {{EOpMix, ParamType::Float2, ParamType::Float2, ParamType::Bool2},
+    {BuiltInId::mix_Float2_Float2_Bool2,
      "float2 mix_emu(float2 x, float2 y, bool2 a)\n"
      "{\n"
      "    return a ? y : x;\n"
      "}\n"},
-    {{EOpMix, ParamType::Float3, ParamType::Float3, ParamType::Bool3},
+    {BuiltInId::mix_Float3_Float3_Bool3,
      "float3 mix_emu(float3 x, float3 y, bool3 a)\n"
      "{\n"
      "    return a ? y : x;\n"
      "}\n"},
-    {{EOpMix, ParamType::Float4, ParamType::Float4, ParamType::Bool4},
+    {BuiltInId::mix_Float4_Float4_Bool4,
      "float4 mix_emu(float4 x, float4 y, bool4 a)\n"
      "{\n"
      "    return a ? y : x;\n"
      "}\n"},
-    {{EOpBitfieldExtract, ParamType::Uint1, ParamType::Int1, ParamType::Int1},
+    {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"},
-    {{EOpBitfieldExtract, ParamType::Uint2, ParamType::Int1, ParamType::Int1},
+    {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"},
-    {{EOpBitfieldExtract, ParamType::Uint3, ParamType::Int1, ParamType::Int1},
+    {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"},
-    {{EOpBitfieldExtract, ParamType::Uint4, ParamType::Int1, ParamType::Int1},
+    {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"},
-    {{EOpBitfieldExtract, ParamType::Int1, ParamType::Int1, ParamType::Int1},
+    {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"},
-    {{EOpBitfieldExtract, ParamType::Int2, ParamType::Int1, ParamType::Int1},
+    {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"},
-    {{EOpBitfieldExtract, ParamType::Int3, ParamType::Int1, ParamType::Int1},
+    {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"},
-    {{EOpBitfieldExtract, ParamType::Int4, ParamType::Int1, ParamType::Int1},
+    {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"},
-    {{EOpBitfieldInsert, ParamType::Uint1, ParamType::Uint1, ParamType::Int1, ParamType::Int1},
+    {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"},
-    {{EOpBitfieldInsert, ParamType::Uint2, ParamType::Uint2, ParamType::Int1, ParamType::Int1},
+    {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"},
-    {{EOpBitfieldInsert, ParamType::Uint3, ParamType::Uint3, ParamType::Int1, ParamType::Int1},
+    {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"},
-    {{EOpBitfieldInsert, ParamType::Uint4, ParamType::Uint4, ParamType::Int1, ParamType::Int1},
+    {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"},
-    {{EOpBitfieldInsert, ParamType::Int1, ParamType::Int1, ParamType::Int1, ParamType::Int1},
+    {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"},
-    {{EOpBitfieldInsert, ParamType::Int2, ParamType::Int2, ParamType::Int1, ParamType::Int1},
+    {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"},
-    {{EOpBitfieldInsert, ParamType::Int3, ParamType::Int3, ParamType::Int1, ParamType::Int1},
+    {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"},
-    {{EOpBitfieldInsert, ParamType::Int4, ParamType::Int4, ParamType::Int1, ParamType::Int1},
+    {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"},
-    {{EOpUaddCarry, ParamType::Uint1, ParamType::Uint1, ParamType::Uint1},
+    {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"},
-    {{EOpUaddCarry, ParamType::Uint2, ParamType::Uint2, ParamType::Uint2},
+    {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"},
-    {{EOpUaddCarry, ParamType::Uint3, ParamType::Uint3, ParamType::Uint3},
+    {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"},
-    {{EOpUaddCarry, ParamType::Uint4, ParamType::Uint4, ParamType::Uint4},
+    {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"},
-    {{EOpUsubBorrow, ParamType::Uint1, ParamType::Uint1, ParamType::Uint1},
+    {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"},
-    {{EOpUsubBorrow, ParamType::Uint2, ParamType::Uint2, ParamType::Uint2},
+    {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"},
-    {{EOpUsubBorrow, ParamType::Uint3, ParamType::Uint3, ParamType::Uint3},
+    {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"},
-    {{EOpUsubBorrow, ParamType::Uint4, ParamType::Uint4, ParamType::Uint4},
+    {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.
-    {{EOpTanh, ParamType::Float1},
+    {BuiltInId::tanh_Float1,
      "float tanh_emu(float x)\n"
      "{\n"
      "    return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
      "}\n"},
-    {{EOpTanh, ParamType::Float2},
+    {BuiltInId::tanh_Float2,
      "float2 tanh_emu(float2 x)\n"
      "{\n"
      "    return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
      "}\n"},
-    {{EOpTanh, ParamType::Float3},
+    {BuiltInId::tanh_Float3,
      "float3 tanh_emu(float3 x)\n"
      "{\n"
      "    return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
      "}\n"},
-    {{EOpTanh, ParamType::Float4},
+    {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(const FunctionId &functionID)
+const char *FindHLSLFunction(int uniqueId)
 {
     for (size_t index = 0; index < ArraySize(g_hlslFunctions); ++index)
     {
         const auto &function = g_hlslFunctions[index];
-        if (function.id == functionID)
+        if (function.id == uniqueId)
         {
             return function.body;
         }
     }
 
     return nullptr;
 }
 }  // namespace sh
--- a/gfx/angle/checkout/src/compiler/translator/glslang.y
+++ b/gfx/angle/checkout/src/compiler/translator/glslang.y
@@ -645,31 +645,31 @@ function_declarator
 
 
 function_header_with_parameters
     : function_header parameter_declaration {
         // Add the parameter
         $$ = $1;
         if ($2.type->getBasicType() != EbtVoid)
         {
-            $1->addParameter($2.turnToConst());
+            $1->addParameter($2.createVariable(&context->symbolTable));
         }
     }
     | function_header_with_parameters COMMA parameter_declaration {
         $$ = $1;
         // Only first parameter of one-parameter functions can be void
         // The check for named parameters not being void is done in parameter_declarator
         if ($3.type->getBasicType() == EbtVoid)
         {
             // This parameter > first is void
             context->error(@2, "cannot be a parameter type except for '(void)'", "void");
         }
         else
         {
-            $1->addParameter($3.turnToConst());
+            $1->addParameter($3.createVariable(&context->symbolTable));
         }
     }
     ;
 
 function_header
     : fully_specified_type IDENTIFIER LEFT_PAREN {
         $$ = context->parseFunctionHeader($1, ImmutableString($2.string), @2);
 
@@ -1299,21 +1299,21 @@ compound_statement_no_new_scope
         $2->setLine(@$);
         $$ = $2;
     }
     ;
 
 statement_list
     : statement {
         $$ = new TIntermBlock();
-        $$->appendStatement($1);
+        context->appendStatement($$, $1);
     }
     | statement_list statement {
         $$ = $1;
-        $$->appendStatement($2);
+        context->appendStatement($$, $2);
     }
     ;
 
 expression_statement
     : SEMICOLON  { $$ = context->addEmptyStatement(@$); }
     | expression SEMICOLON  { $$ = $1; }
     ;
 
--- a/gfx/angle/checkout/src/compiler/translator/glslang_tab.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/glslang_tab.cpp
@@ -3263,17 +3263,17 @@ yyreduce:
 
   case 100:
 
     {
         // 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).turnToConst());
+            (yyvsp[-1].interm.function)->addParameter((yyvsp[0].interm.param).createVariable(&context->symbolTable));
         }
     }
 
     break;
 
   case 101:
 
     {
@@ -3282,17 +3282,17 @@ yyreduce:
         // 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
         {
-            (yyvsp[-2].interm.function)->addParameter((yyvsp[0].interm.param).turnToConst());
+            (yyvsp[-2].interm.function)->addParameter((yyvsp[0].interm.param).createVariable(&context->symbolTable));
         }
     }
 
     break;
 
   case 102:
 
     {
@@ -4625,26 +4625,26 @@ yyreduce:
     }
 
     break;
 
   case 262:
 
     {
         (yyval.interm.intermBlock) = new TIntermBlock();
-        (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
+        context->appendStatement((yyval.interm.intermBlock), (yyvsp[0].interm.intermNode));
     }
 
     break;
 
   case 263:
 
     {
         (yyval.interm.intermBlock) = (yyvsp[-1].interm.intermBlock);
-        (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
+        context->appendStatement((yyval.interm.intermBlock), (yyvsp[0].interm.intermNode));
     }
 
     break;
 
   case 264:
 
     { (yyval.interm.intermNode) = context->addEmptyStatement((yyloc)); }
 
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/AddAndTrueToLoopCondition.cpp
@@ -0,0 +1,58 @@
+//
+// Copyright (c) 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/AddAndTrueToLoopCondition.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
+
+void AddAndTrueToLoopCondition(TIntermNode *root)
+{
+    AddAndTrueToLoopConditionTraverser traverser;
+    root->traverse(&traverser);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/AddAndTrueToLoopCondition.h
@@ -0,0 +1,20 @@
+//
+// Copyright (c) 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_ADDANDTRUETOLOOPCONDITION_H_
+#define COMPILER_TRANSLATOR_TREEOPS_ADDANDTRUETOLOOPCONDITION_H_
+
+class TIntermNode;
+namespace sh
+{
+
+void AddAndTrueToLoopCondition(TIntermNode *root);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_ADDANDTRUETOLOOPCONDITION_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/AddDefaultReturnStatements.cpp
@@ -0,0 +1,58 @@
+//
+// Copyright (c) 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/AddDefaultReturnStatements.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
+
+void AddDefaultReturnStatements(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);
+        }
+    }
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/AddDefaultReturnStatements.h
@@ -0,0 +1,22 @@
+//
+// Copyright (c) 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_ADDDEFAULTRETURNSTATEMENTS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_ADDDEFAULTRETURNSTATEMENTS_H_
+
+class TIntermBlock;
+
+namespace sh
+{
+
+void AddDefaultReturnStatements(TIntermBlock *root);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_ADDDEFAULTRETURNSTATEMENTS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ArrayReturnValueToOutParameter.cpp
@@ -0,0 +1,229 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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/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:
+    static void apply(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 = new TIntermSequence();
+    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;
+}
+
+void ArrayReturnValueToOutParameterTraverser::apply(TIntermNode *root, TSymbolTable *symbolTable)
+{
+    ArrayReturnValueToOutParameterTraverser arrayReturnValueToOutParam(symbolTable);
+    root->traverse(&arrayReturnValueToOutParam);
+    arrayReturnValueToOutParam.updateTree();
+}
+
+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(EvqOut);
+            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>(), 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.push_back(
+                NodeReplaceWithMultipleEntry(parentBlock, node, 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.push_back(
+            NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(), node, 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
+
+void ArrayReturnValueToOutParameter(TIntermNode *root, TSymbolTable *symbolTable)
+{
+    ArrayReturnValueToOutParameterTraverser::apply(root, symbolTable);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ArrayReturnValueToOutParameter.h
@@ -0,0 +1,22 @@
+//
+// Copyright (c) 2002-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.
+//
+// The ArrayReturnValueToOutParameter function changes return values of an array type to out
+// parameters in function definitions, prototypes and call sites.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_ARRAYRETURNVALUETOOUTPARAMETER_H_
+#define COMPILER_TRANSLATOR_TREEOPS_ARRAYRETURNVALUETOOUTPARAMETER_H_
+
+namespace sh
+{
+
+class TIntermNode;
+class TSymbolTable;
+
+void ArrayReturnValueToOutParameter(TIntermNode *root, TSymbolTable *symbolTable);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_ARRAYRETURNVALUETOOUTPARAMETER_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/BreakVariableAliasingInInnerLoops.cpp
@@ -0,0 +1,107 @@
+//
+// Copyright (c) 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 "BreakVariableAliasingInInnerLoops.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)
+    {
+        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)
+    {
+        if (visit == PreVisit)
+        {
+            mLoopLevel++;
+        }
+        else
+        {
+            ASSERT(mLoopLevel > 0);
+            mLoopLevel--;
+        }
+
+        return true;
+    }
+
+  private:
+    int mLoopLevel = 0;
+};
+
+}  // anonymous namespace
+
+void BreakVariableAliasingInInnerLoops(TIntermNode *root)
+{
+    AliasingBreaker breaker;
+    root->traverse(&breaker);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/BreakVariableAliasingInInnerLoops.h
@@ -0,0 +1,23 @@
+//
+// Copyright (c) 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_BREAKVARIABLEALIASINGININNERLOOPS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_BREAKVARIABLEALIASINGININNERLOOPS_H_
+
+class TIntermNode;
+
+namespace sh
+{
+
+void BreakVariableAliasingInInnerLoops(TIntermNode *root);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_BREAKVARIABLEALIASINGININNERLOOPS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampFragDepth.cpp
@@ -0,0 +1,54 @@
+//
+// Copyright (c) 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/ClampFragDepth.h"
+
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/BuiltIn_autogen.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
+{
+
+void ClampFragDepth(TIntermBlock *root, TSymbolTable *symbolTable)
+{
+    // Only clamp gl_FragDepth if it's used in the shader.
+    if (!FindSymbolNode(root, ImmutableString("gl_FragDepth")))
+    {
+        return;
+    }
+
+    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 = new TIntermSequence();
+    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);
+
+    RunAtTheEndOfShader(root, assignFragDepth, symbolTable);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampFragDepth.h
@@ -0,0 +1,24 @@
+//
+// Copyright (c) 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_CLAMPFRAGDEPTH_H_
+#define COMPILER_TRANSLATOR_TREEOPS_CLAMPFRAGDEPTH_H_
+
+namespace sh
+{
+
+class TIntermBlock;
+class TSymbolTable;
+
+void ClampFragDepth(TIntermBlock *root, TSymbolTable *symbolTable);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_CLAMPFRAGDEPTH_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.cpp
@@ -0,0 +1,48 @@
+//
+// Copyright (c) 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_autogen.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
+{
+
+void ClampPointSize(TIntermBlock *root, float maxPointSize, TSymbolTable *symbolTable)
+{
+    // Only clamp gl_PointSize if it's used in the shader.
+    if (!FindSymbolNode(root, ImmutableString("gl_PointSize")))
+    {
+        return;
+    }
+
+    TIntermSymbol *pointSizeNode = new TIntermSymbol(BuiltInVariable::gl_PointSize());
+
+    TConstantUnion *maxPointSizeConstant = new TConstantUnion();
+    maxPointSizeConstant->setFConst(maxPointSize);
+    TIntermConstantUnion *maxPointSizeNode =
+        new TIntermConstantUnion(maxPointSizeConstant, TType(EbtFloat, EbpHigh, EvqConst));
+
+    // min(gl_PointSize, maxPointSize)
+    TIntermSequence *minArguments = new TIntermSequence();
+    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);
+
+    RunAtTheEndOfShader(root, assignPointSize, symbolTable);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.h
@@ -0,0 +1,22 @@
+//
+// Copyright (c) 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_
+
+namespace sh
+{
+
+class TIntermBlock;
+class TSymbolTable;
+
+void ClampPointSize(TIntermBlock *root, float maxPointSize, TSymbolTable *symbolTable);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_CLAMPPOINTSIZE_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.cpp
@@ -0,0 +1,195 @@
+//
+// Copyright (c) 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/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_ops/InitializeVariables.h"
+#include "compiler/translator/tree_util/BuiltIn_autogen.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, EbpHigh, EvqConst));
+
+    // Create a uint(gl_InstanceID) node.
+    TIntermSequence *glInstanceIDSymbolCastArguments = new TIntermSequence();
+    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 = new TIntermSequence();
+    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);
+}
+
+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);
+}
+
+// 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 = new TIntermSequence();
+    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
+
+void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
+                                                 unsigned numberOfViews,
+                                                 GLenum shaderType,
+                                                 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);
+    ReplaceVariable(root, BuiltInVariable::gl_ViewID_OVR(), viewID);
+    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);
+        ReplaceVariable(root, BuiltInVariable::gl_InstanceID(), instanceID);
+
+        TIntermSequence *initializers = new TIntermSequence();
+        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 & SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER) != 0u;
+        // 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);
+    }
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h
@@ -0,0 +1,48 @@
+//
+// Copyright (c) 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 SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER 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"
+
+namespace sh
+{
+
+class TIntermBlock;
+class TSymbolTable;
+
+void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
+                                                 unsigned numberOfViews,
+                                                 GLenum shaderType,
+                                                 ShCompileOptions compileOptions,
+                                                 ShShaderOutput shaderOutput,
+                                                 TSymbolTable *symbolTable);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.cpp
@@ -0,0 +1,167 @@
+//
+// Copyright (c) 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/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,
+                             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())
+        {
+            // 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, 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>(), false);
+
+    TIntermFunctionPrototype *initGlobalsFunctionPrototype =
+        CreateInternalFunctionPrototypeNode(*initGlobalsFunction);
+    root->getSequence()->insert(root->getSequence()->begin(), initGlobalsFunctionPrototype);
+    TIntermFunctionDefinition *initGlobalsFunctionDefinition =
+        CreateInternalFunctionDefinitionNode(*initGlobalsFunction, initGlobalsBlock);
+    root->appendStatement(initGlobalsFunctionDefinition);
+
+    TIntermAggregate *initGlobalsCall =
+        TIntermAggregate::CreateFunctionCall(*initGlobalsFunction, new TIntermSequence());
+
+    TIntermBlock *mainBody = FindMainBody(root);
+    mainBody->getSequence()->insert(mainBody->getSequence()->begin(), initGlobalsCall);
+}
+
+}  // namespace
+
+void DeferGlobalInitializers(TIntermBlock *root,
+                             bool initializeUninitializedGlobals,
+                             bool canUseLoopsToInitialize,
+                             bool highPrecisionSupported,
+                             TSymbolTable *symbolTable)
+{
+    TIntermSequence *deferredInitializers = new TIntermSequence();
+    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,
+                                    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());
+        ReplaceVariable(root, var, replacement);
+    }
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.h
@@ -0,0 +1,33 @@
+//
+// Copyright (c) 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_
+
+namespace sh
+{
+
+class TIntermBlock;
+class TSymbolTable;
+
+void DeferGlobalInitializers(TIntermBlock *root,
+                             bool initializeUninitializedGlobals,
+                             bool canUseLoopsToInitialize,
+                             bool highPrecisionSupported,
+                             TSymbolTable *symbolTable);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_DEFERGLOBALINITIALIZERS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp
@@ -0,0 +1,132 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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/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)
+    {
+    }
+
+    void broadcastGLFragColor(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;
+    }
+}
+
+void GLFragColorBroadcastTraverser::broadcastGLFragColor(TIntermBlock *root)
+{
+    ASSERT(mMaxDrawBuffers > 1);
+    if (!mGLFragColorUsed)
+    {
+        return;
+    }
+
+    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));
+    }
+    RunAtTheEndOfShader(root, broadcastBlock, mSymbolTable);
+}
+
+}  // namespace anonymous
+
+void EmulateGLFragColorBroadcast(TIntermBlock *root,
+                                 int maxDrawBuffers,
+                                 std::vector<sh::OutputVariable> *outputVariables,
+                                 TSymbolTable *symbolTable,
+                                 int shaderVersion)
+{
+    ASSERT(maxDrawBuffers > 1);
+    GLFragColorBroadcastTraverser traverser(maxDrawBuffers, symbolTable, shaderVersion);
+    root->traverse(&traverser);
+    if (traverser.isGLFragColorUsed())
+    {
+        traverser.updateTree();
+        traverser.broadcastGLFragColor(root);
+        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);
+            }
+        }
+    }
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.h
@@ -0,0 +1,31 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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>
+
+namespace sh
+{
+struct OutputVariable;
+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.
+void EmulateGLFragColorBroadcast(TIntermBlock *root,
+                                 int maxDrawBuffers,
+                                 std::vector<OutputVariable> *outputVariables,
+                                 TSymbolTable *symbolTable,
+                                 int shaderVersion);
+}
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_EMULATEGLFRAGCOLORBROADCAST_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulatePrecision.cpp
@@ -0,0 +1,780 @@
+//
+// Copyright (c) 2002-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/tree_ops/EmulatePrecision.h"
+
+#include "compiler/translator/FunctionLookup.h"
+
+#include <memory>
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kParamXName("x");
+constexpr const ImmutableString kParamYName("y");
+constexpr const ImmutableString kAngleFrmString("angle_frm");
+constexpr const ImmutableString kAngleFrlString("angle_frl");
+
+class RoundingHelperWriter : angle::NonCopyable
+{
+  public:
+    static RoundingHelperWriter *createHelperWriter(const ShShaderOutput outputLanguage);
+
+    void writeCommonRoundingHelpers(TInfoSinkBase &sink, const int shaderVersion);
+    void writeCompoundAssignmentHelper(TInfoSinkBase &sink,
+                                       const char *lType,
+                                       const char *rType,
+                                       const char *opStr,
+                                       const char *opNameStr);
+
+    virtual ~RoundingHelperWriter() {}
+
+  protected:
+    RoundingHelperWriter(const ShShaderOutput outputLanguage) : mOutputLanguage(outputLanguage) {}
+    RoundingHelperWriter() = delete;
+
+    const ShShaderOutput mOutputLanguage;
+
+  private:
+    virtual std::string getTypeString(const char *glslType)                               = 0;
+    virtual void writeFloatRoundingHelpers(TInfoSinkBase &sink)                           = 0;
+    virtual void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) = 0;
+    virtual void writeMatrixRoundingHelper(TInfoSinkBase &sink,
+                                           const unsigned int columns,
+                                           const unsigned int rows,
+                                           const char *functionName)                      = 0;
+};
+
+class RoundingHelperWriterGLSL : public RoundingHelperWriter
+{
+  public:
+    RoundingHelperWriterGLSL(const ShShaderOutput outputLanguage)
+        : RoundingHelperWriter(outputLanguage)
+    {
+    }
+
+  private:
+    std::string getTypeString(const char *glslType) override;
+    void writeFloatRoundingHelpers(TInfoSinkBase &sink) override;
+    void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) override;
+    void writeMatrixRoundingHelper(TInfoSinkBase &sink,
+                                   const unsigned int columns,
+                                   const unsigned int rows,
+                                   const char *functionName) override;
+};
+
+class RoundingHelperWriterESSL : public RoundingHelperWriterGLSL
+{
+  public:
+    RoundingHelperWriterESSL(const ShShaderOutput outputLanguage)
+        : RoundingHelperWriterGLSL(outputLanguage)
+    {
+    }
+
+  private:
+    std::string getTypeString(const char *glslType) override;
+};
+
+class RoundingHelperWriterHLSL : public RoundingHelperWriter
+{
+  public:
+    RoundingHelperWriterHLSL(const ShShaderOutput outputLanguage)
+        : RoundingHelperWriter(outputLanguage)
+    {
+    }
+
+  private:
+    std::string getTypeString(const char *glslType) override;
+    void writeFloatRoundingHelpers(TInfoSinkBase &sink) override;
+    void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) override;
+    void writeMatrixRoundingHelper(TInfoSinkBase &sink,
+                                   const unsigned int columns,
+                                   const unsigned int rows,
+                                   const char *functionName) override;
+};
+
+RoundingHelperWriter *RoundingHelperWriter::createHelperWriter(const ShShaderOutput outputLanguage)
+{
+    ASSERT(EmulatePrecision::SupportedInLanguage(outputLanguage));
+    switch (outputLanguage)
+    {
+        case SH_HLSL_4_1_OUTPUT:
+            return new RoundingHelperWriterHLSL(outputLanguage);
+        case SH_ESSL_OUTPUT:
+            return new RoundingHelperWriterESSL(outputLanguage);
+        default:
+            return new RoundingHelperWriterGLSL(outputLanguage);
+    }
+}
+
+void RoundingHelperWriter::writeCommonRoundingHelpers(TInfoSinkBase &sink, const int shaderVersion)
+{
+    // Write the angle_frm functions that round floating point numbers to
+    // half precision, and angle_frl functions that round them to minimum lowp
+    // precision.
+
+    writeFloatRoundingHelpers(sink);
+    writeVectorRoundingHelpers(sink, 2);
+    writeVectorRoundingHelpers(sink, 3);
+    writeVectorRoundingHelpers(sink, 4);
+    if (shaderVersion > 100)
+    {
+        for (unsigned int columns = 2; columns <= 4; ++columns)
+        {
+            for (unsigned int rows = 2; rows <= 4; ++rows)
+            {
+                writeMatrixRoundingHelper(sink, columns, rows, "angle_frm");
+                writeMatrixRoundingHelper(sink, columns, rows, "angle_frl");
+            }
+        }
+    }
+    else
+    {
+        for (unsigned int size = 2; size <= 4; ++size)
+        {
+            writeMatrixRoundingHelper(sink, size, size, "angle_frm");
+            writeMatrixRoundingHelper(sink, size, size, "angle_frl");
+        }
+    }
+}
+
+void RoundingHelperWriter::writeCompoundAssignmentHelper(TInfoSinkBase &sink,
+                                                         const char *lType,
+                                                         const char *rType,
+                                                         const char *opStr,
+                                                         const char *opNameStr)
+{
+    std::string lTypeStr = getTypeString(lType);
+    std::string rTypeStr = getTypeString(rType);
+
+    // Note that y should be passed through angle_frm at the function call site,
+    // but x can't be passed through angle_frm there since it is an inout parameter.
+    // So only pass x and the result through angle_frm here.
+    // clang-format off
+    sink <<
+        lTypeStr << " angle_compound_" << opNameStr << "_frm(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n"
+        "    x = angle_frm(angle_frm(x) " << opStr << " y);\n"
+        "    return x;\n"
+        "}\n";
+    sink <<
+        lTypeStr << " angle_compound_" << opNameStr << "_frl(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n"
+        "    x = angle_frl(angle_frl(x) " << opStr << " y);\n"
+        "    return x;\n"
+        "}\n";
+    // clang-format on
+}
+
+std::string RoundingHelperWriterGLSL::getTypeString(const char *glslType)
+{
+    return glslType;
+}
+
+std::string RoundingHelperWriterESSL::getTypeString(const char *glslType)
+{
+    std::stringstream typeStrStr;
+    typeStrStr << "highp " << glslType;
+    return typeStrStr.str();
+}
+
+void RoundingHelperWriterGLSL::writeFloatRoundingHelpers(TInfoSinkBase &sink)
+{
+    // Unoptimized version of angle_frm for single floats:
+    //
+    // int webgl_maxNormalExponent(in int exponentBits)
+    // {
+    //     int possibleExponents = int(exp2(float(exponentBits)));
+    //     int exponentBias = possibleExponents / 2 - 1;
+    //     int allExponentBitsOne = possibleExponents - 1;
+    //     return (allExponentBitsOne - 1) - exponentBias;
+    // }
+    //
+    // float angle_frm(in float x)
+    // {
+    //     int mantissaBits = 10;
+    //     int exponentBits = 5;
+    //     float possibleMantissas = exp2(float(mantissaBits));
+    //     float mantissaMax = 2.0 - 1.0 / possibleMantissas;
+    //     int maxNE = webgl_maxNormalExponent(exponentBits);
+    //     float max = exp2(float(maxNE)) * mantissaMax;
+    //     if (x > max)
+    //     {
+    //         return max;
+    //     }
+    //     if (x < -max)
+    //     {
+    //         return -max;
+    //     }
+    //     float exponent = floor(log2(abs(x)));
+    //     if (abs(x) == 0.0 || exponent < -float(maxNE))
+    //     {
+    //         return 0.0 * sign(x)
+    //     }
+    //     x = x * exp2(-(exponent - float(mantissaBits)));
+    //     x = sign(x) * floor(abs(x));
+    //     return x * exp2(exponent - float(mantissaBits));
+    // }
+
+    // All numbers with a magnitude less than 2^-15 are subnormal, and are
+    // flushed to zero.
+
+    // Note the constant numbers below:
+    // a) 65504 is the maximum possible mantissa (1.1111111111 in binary) times
+    //    2^15, the maximum normal exponent.
+    // b) 10.0 is the number of mantissa bits.
+    // c) -25.0 is the minimum normal half-float exponent -15.0 minus the number
+    //    of mantissa bits.
+    // d) + 1e-30 is to make sure the argument of log2() won't be zero. It can
+    //    only affect the result of log2 on x where abs(x) < 1e-22. Since these
+    //    numbers will be flushed to zero either way (2^-15 is the smallest
+    //    normal positive number), this does not introduce any error.
+
+    std::string floatType = getTypeString("float");
+
+    // clang-format off
+    sink <<
+        floatType << " angle_frm(in " << floatType << " x) {\n"
+        "    x = clamp(x, -65504.0, 65504.0);\n"
+        "    " << floatType << " exponent = floor(log2(abs(x) + 1e-30)) - 10.0;\n"
+        "    bool isNonZero = (exponent >= -25.0);\n"
+        "    x = x * exp2(-exponent);\n"
+        "    x = sign(x) * floor(abs(x));\n"
+        "    return x * exp2(exponent) * float(isNonZero);\n"
+        "}\n";
+
+    sink <<
+        floatType << " angle_frl(in " << floatType << " x) {\n"
+        "    x = clamp(x, -2.0, 2.0);\n"
+        "    x = x * 256.0;\n"
+        "    x = sign(x) * floor(abs(x));\n"
+        "    return x * 0.00390625;\n"
+        "}\n";
+    // clang-format on
+}
+
+void RoundingHelperWriterGLSL::writeVectorRoundingHelpers(TInfoSinkBase &sink,
+                                                          const unsigned int size)
+{
+    std::stringstream vecTypeStrStr;
+    vecTypeStrStr << "vec" << size;
+    std::string vecType = getTypeString(vecTypeStrStr.str().c_str());
+
+    // clang-format off
+    sink <<
+        vecType << " angle_frm(in " << vecType << " v) {\n"
+        "    v = clamp(v, -65504.0, 65504.0);\n"
+        "    " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n"
+        "    bvec" << size << " isNonZero = greaterThanEqual(exponent, vec" << size << "(-25.0));\n"
+        "    v = v * exp2(-exponent);\n"
+        "    v = sign(v) * floor(abs(v));\n"
+        "    return v * exp2(exponent) * vec" << size << "(isNonZero);\n"
+        "}\n";
+
+    sink <<
+        vecType << " angle_frl(in " << vecType << " v) {\n"
+        "    v = clamp(v, -2.0, 2.0);\n"
+        "    v = v * 256.0;\n"
+        "    v = sign(v) * floor(abs(v));\n"
+        "    return v * 0.00390625;\n"
+        "}\n";
+    // clang-format on
+}
+
+void RoundingHelperWriterGLSL::writeMatrixRoundingHelper(TInfoSinkBase &sink,
+                                                         const unsigned int columns,
+                                                         const unsigned int rows,
+                                                         const char *functionName)
+{
+    std::stringstream matTypeStrStr;
+    matTypeStrStr << "mat" << columns;
+    if (rows != columns)
+    {
+        matTypeStrStr << "x" << rows;
+    }
+    std::string matType = getTypeString(matTypeStrStr.str().c_str());
+
+    sink << matType << " " << functionName << "(in " << matType << " m) {\n"
+         << "    " << matType << " rounded;\n";
+
+    for (unsigned int i = 0; i < columns; ++i)
+    {
+        sink << "    rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n";
+    }
+
+    sink << "    return rounded;\n"
+            "}\n";
+}
+
+static const char *GetHLSLTypeStr(const char *floatTypeStr)
+{
+    if (strcmp(floatTypeStr, "float") == 0)
+    {
+        return "float";
+    }
+    if (strcmp(floatTypeStr, "vec2") == 0)
+    {
+        return "float2";
+    }
+    if (strcmp(floatTypeStr, "vec3") == 0)
+    {
+        return "float3";
+    }
+    if (strcmp(floatTypeStr, "vec4") == 0)
+    {
+        return "float4";
+    }
+    if (strcmp(floatTypeStr, "mat2") == 0)
+    {
+        return "float2x2";
+    }
+    if (strcmp(floatTypeStr, "mat3") == 0)
+    {
+        return "float3x3";
+    }
+    if (strcmp(floatTypeStr, "mat4") == 0)
+    {
+        return "float4x4";
+    }
+    if (strcmp(floatTypeStr, "mat2x3") == 0)
+    {
+        return "float2x3";
+    }
+    if (strcmp(floatTypeStr, "mat2x4") == 0)
+    {
+        return "float2x4";
+    }
+    if (strcmp(floatTypeStr, "mat3x2") == 0)
+    {
+        return "float3x2";
+    }
+    if (strcmp(floatTypeStr, "mat3x4") == 0)
+    {
+        return "float3x4";
+    }
+    if (strcmp(floatTypeStr, "mat4x2") == 0)
+    {
+        return "float4x2";
+    }
+    if (strcmp(floatTypeStr, "mat4x3") == 0)
+    {
+        return "float4x3";
+    }
+    UNREACHABLE();
+    return nullptr;
+}
+
+std::string RoundingHelperWriterHLSL::getTypeString(const char *glslType)
+{
+    return GetHLSLTypeStr(glslType);
+}
+
+void RoundingHelperWriterHLSL::writeFloatRoundingHelpers(TInfoSinkBase &sink)
+{
+    // In HLSL scalars are the same as 1-vectors.
+    writeVectorRoundingHelpers(sink, 1);
+}
+
+void RoundingHelperWriterHLSL::writeVectorRoundingHelpers(TInfoSinkBase &sink,
+                                                          const unsigned int size)
+{
+    std::stringstream vecTypeStrStr;
+    vecTypeStrStr << "float" << size;
+    std::string vecType = vecTypeStrStr.str();
+
+    // clang-format off
+    sink <<
+        vecType << " angle_frm(" << vecType << " v) {\n"
+        "    v = clamp(v, -65504.0, 65504.0);\n"
+        "    " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n"
+        "    bool" << size << " isNonZero = exponent < -25.0;\n"
+        "    v = v * exp2(-exponent);\n"
+        "    v = sign(v) * floor(abs(v));\n"
+        "    return v * exp2(exponent) * (float" << size << ")(isNonZero);\n"
+        "}\n";
+
+    sink <<
+        vecType << " angle_frl(" << vecType << " v) {\n"
+        "    v = clamp(v, -2.0, 2.0);\n"
+        "    v = v * 256.0;\n"
+        "    v = sign(v) * floor(abs(v));\n"
+        "    return v * 0.00390625;\n"
+        "}\n";
+    // clang-format on
+}
+
+void RoundingHelperWriterHLSL::writeMatrixRoundingHelper(TInfoSinkBase &sink,
+                                                         const unsigned int columns,
+                                                         const unsigned int rows,
+                                                         const char *functionName)
+{
+    std::stringstream matTypeStrStr;
+    matTypeStrStr << "float" << columns << "x" << rows;
+    std::string matType = matTypeStrStr.str();
+
+    sink << matType << " " << functionName << "(" << matType << " m) {\n"
+         << "    " << matType << " rounded;\n";
+
+    for (unsigned int i = 0; i < columns; ++i)
+    {
+        sink << "    rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n";
+    }
+
+    sink << "    return rounded;\n"
+            "}\n";
+}
+
+bool canRoundFloat(const TType &type)
+{
+    return type.getBasicType() == EbtFloat && !type.isArray() &&
+           (type.getPrecision() == EbpLow || type.getPrecision() == EbpMedium);
+}
+
+bool ParentUsesResult(TIntermNode *parent, TIntermTyped *node)
+{
+    if (!parent)
+    {
+        return false;
+    }
+
+    TIntermBlock *blockParent = parent->getAsBlock();
+    // If the parent is a block, the result is not assigned anywhere,
+    // so rounding it is not needed. In particular, this can avoid a lot of
+    // unnecessary rounding of unused return values of assignment.
+    if (blockParent)
+    {
+        return false;
+    }
+    TIntermBinary *binaryParent = parent->getAsBinaryNode();
+    if (binaryParent && binaryParent->getOp() == EOpComma && (binaryParent->getRight() != node))
+    {
+        return false;
+    }
+    return true;
+}
+
+bool ParentConstructorTakesCareOfRounding(TIntermNode *parent, TIntermTyped *node)
+{
+    if (!parent)
+    {
+        return false;
+    }
+    TIntermAggregate *parentConstructor = parent->getAsAggregate();
+    if (!parentConstructor || parentConstructor->getOp() != EOpConstruct)
+    {
+        return false;
+    }
+    if (parentConstructor->getPrecision() != node->getPrecision())
+    {
+        return false;
+    }
+    return canRoundFloat(parentConstructor->getType());
+}
+
+}  // namespace anonymous
+
+EmulatePrecision::EmulatePrecision(TSymbolTable *symbolTable)
+    : TLValueTrackingTraverser(true, true, true, symbolTable), mDeclaringVariables(false)
+{
+}
+
+void EmulatePrecision::visitSymbol(TIntermSymbol *node)
+{
+    TIntermNode *parent = getParentNode();
+    if (canRoundFloat(node->getType()) && ParentUsesResult(parent, node) &&
+        !ParentConstructorTakesCareOfRounding(parent, node) && !mDeclaringVariables &&
+        !isLValueRequiredHere())
+    {
+        TIntermNode *replacement = createRoundingFunctionCallNode(node);
+        queueReplacement(replacement, OriginalNode::BECOMES_CHILD);
+    }
+}
+
+bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node)
+{
+    bool visitChildren = true;
+
+    TOperator op = node->getOp();
+
+    // RHS of initialize is not being declared.
+    if (op == EOpInitialize && visit == InVisit)
+        mDeclaringVariables = false;
+
+    if ((op == EOpIndexDirectStruct) && visit == InVisit)
+        visitChildren = false;
+
+    if (visit != PreVisit)
+        return visitChildren;
+
+    const TType &type = node->getType();
+    bool roundFloat   = canRoundFloat(type);
+
+    if (roundFloat)
+    {
+        switch (op)
+        {
+            // Math operators that can result in a float may need to apply rounding to the return
+            // value. Note that in the case of assignment, the rounding is applied to its return
+            // value here, not the value being assigned.
+            case EOpAssign:
+            case EOpAdd:
+            case EOpSub:
+            case EOpMul:
+            case EOpDiv:
+            case EOpVectorTimesScalar:
+            case EOpVectorTimesMatrix:
+            case EOpMatrixTimesVector:
+            case EOpMatrixTimesScalar:
+            case EOpMatrixTimesMatrix:
+            {
+                TIntermNode *parent = getParentNode();
+                if (!ParentUsesResult(parent, node) ||
+                    ParentConstructorTakesCareOfRounding(parent, node))
+                {
+                    break;
+                }
+                TIntermNode *replacement = createRoundingFunctionCallNode(node);
+                queueReplacement(replacement, OriginalNode::BECOMES_CHILD);
+                break;
+            }
+
+            // Compound assignment cases need to replace the operator with a function call.
+            case EOpAddAssign:
+            {
+                mEmulateCompoundAdd.insert(
+                    TypePair(type.getBuiltInTypeNameString(),
+                             node->getRight()->getType().getBuiltInTypeNameString()));
+                TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(
+                    node->getLeft(), node->getRight(), "add");
+                queueReplacement(replacement, OriginalNode::IS_DROPPED);
+                break;
+            }
+            case EOpSubAssign:
+            {
+                mEmulateCompoundSub.insert(
+                    TypePair(type.getBuiltInTypeNameString(),
+                             node->getRight()->getType().getBuiltInTypeNameString()));
+                TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(
+                    node->getLeft(), node->getRight(), "sub");
+                queueReplacement(replacement, OriginalNode::IS_DROPPED);
+                break;
+            }
+            case EOpMulAssign:
+            case EOpVectorTimesMatrixAssign:
+            case EOpVectorTimesScalarAssign:
+            case EOpMatrixTimesScalarAssign:
+            case EOpMatrixTimesMatrixAssign:
+            {
+                mEmulateCompoundMul.insert(
+                    TypePair(type.getBuiltInTypeNameString(),
+                             node->getRight()->getType().getBuiltInTypeNameString()));
+                TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(
+                    node->getLeft(), node->getRight(), "mul");
+                queueReplacement(replacement, OriginalNode::IS_DROPPED);
+                break;
+            }
+            case EOpDivAssign:
+            {
+                mEmulateCompoundDiv.insert(
+                    TypePair(type.getBuiltInTypeNameString(),
+                             node->getRight()->getType().getBuiltInTypeNameString()));
+                TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(
+                    node->getLeft(), node->getRight(), "div");
+                queueReplacement(replacement, OriginalNode::IS_DROPPED);
+                break;
+            }
+            default:
+                // The rest of the binary operations should not need precision emulation.
+                break;
+        }
+    }
+    return visitChildren;
+}
+
+bool EmulatePrecision::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+    // Variable or interface block declaration.
+    if (visit == PreVisit)
+    {
+        mDeclaringVariables = true;
+    }
+    else if (visit == InVisit)
+    {
+        mDeclaringVariables = true;
+    }
+    else
+    {
+        mDeclaringVariables = false;
+    }
+    return true;
+}
+
+bool EmulatePrecision::visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node)
+{
+    return false;
+}
+
+bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+    if (visit != PreVisit)
+        return true;
+
+    // User-defined function return values are not rounded. The calculations that produced
+    // the value inside the function definition should have been rounded.
+    TOperator op = node->getOp();
+    if (op == EOpCallInternalRawFunction || op == EOpCallFunctionInAST ||
+        (op == EOpConstruct && node->getBasicType() == EbtStruct))
+    {
+        return true;
+    }
+
+    TIntermNode *parent = getParentNode();
+    if (canRoundFloat(node->getType()) && ParentUsesResult(parent, node) &&
+        !ParentConstructorTakesCareOfRounding(parent, node))
+    {
+        TIntermNode *replacement = createRoundingFunctionCallNode(node);
+        queueReplacement(replacement, OriginalNode::BECOMES_CHILD);
+    }
+    return true;
+}
+
+bool EmulatePrecision::visitUnary(Visit visit, TIntermUnary *node)
+{
+    switch (node->getOp())
+    {
+        case EOpNegative:
+        case EOpLogicalNot:
+        case EOpPostIncrement:
+        case EOpPostDecrement:
+        case EOpPreIncrement:
+        case EOpPreDecrement:
+        case EOpLogicalNotComponentWise:
+            break;
+        default:
+            if (canRoundFloat(node->getType()) && visit == PreVisit)
+            {
+                TIntermNode *replacement = createRoundingFunctionCallNode(node);
+                queueReplacement(replacement, OriginalNode::BECOMES_CHILD);
+            }
+            break;
+    }
+
+    return true;
+}
+
+void EmulatePrecision::writeEmulationHelpers(TInfoSinkBase &sink,
+                                             const int shaderVersion,
+                                             const ShShaderOutput outputLanguage)
+{
+    std::unique_ptr<RoundingHelperWriter> roundingHelperWriter(
+        RoundingHelperWriter::createHelperWriter(outputLanguage));
+
+    roundingHelperWriter->writeCommonRoundingHelpers(sink, shaderVersion);
+
+    EmulationSet::const_iterator it;
+    for (it = mEmulateCompoundAdd.begin(); it != mEmulateCompoundAdd.end(); it++)
+        roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "+", "add");
+    for (it = mEmulateCompoundSub.begin(); it != mEmulateCompoundSub.end(); it++)
+        roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "-", "sub");
+    for (it = mEmulateCompoundDiv.begin(); it != mEmulateCompoundDiv.end(); it++)
+        roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "/", "div");
+    for (it = mEmulateCompoundMul.begin(); it != mEmulateCompoundMul.end(); it++)
+        roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "*", "mul");
+}
+
+// static
+bool EmulatePrecision::SupportedInLanguage(const ShShaderOutput outputLanguage)
+{
+    switch (outputLanguage)
+    {
+        case SH_HLSL_4_1_OUTPUT:
+        case SH_ESSL_OUTPUT:
+            return true;
+        default:
+            // Other languages not yet supported
+            return (outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT ||
+                    sh::IsGLSL130OrNewer(outputLanguage));
+    }
+}
+
+const TFunction *EmulatePrecision::getInternalFunction(const ImmutableString &functionName,
+                                                       const TType &returnType,
+                                                       TIntermSequence *arguments,
+                                                       const TVector<const TVariable *> &parameters,
+                                                       bool knownToNotHaveSideEffects)
+{
+    ImmutableString mangledName = TFunctionLookup::GetMangledName(functionName.data(), *arguments);
+    if (mInternalFunctions.find(mangledName) == mInternalFunctions.end())
+    {
+        TFunction *func = new TFunction(mSymbolTable, functionName, SymbolType::AngleInternal,
+                                        new TType(returnType), knownToNotHaveSideEffects);
+        ASSERT(parameters.size() == arguments->size());
+        for (size_t i = 0; i < parameters.size(); ++i)
+        {
+            func->addParameter(parameters[i]);
+        }
+        mInternalFunctions[mangledName] = func;
+    }
+    return mInternalFunctions[mangledName];
+}
+
+TIntermAggregate *EmulatePrecision::createRoundingFunctionCallNode(TIntermTyped *roundedChild)
+{
+    const ImmutableString *roundFunctionName = &kAngleFrmString;
+    if (roundedChild->getPrecision() == EbpLow)
+        roundFunctionName = &kAngleFrlString;
+    TIntermSequence *arguments = new TIntermSequence();
+    arguments->push_back(roundedChild);
+
+    TVector<const TVariable *> parameters;
+    TType *paramType = new TType(roundedChild->getType());
+    paramType->setPrecision(EbpHigh);
+    paramType->setQualifier(EvqIn);
+    parameters.push_back(new TVariable(mSymbolTable, kParamXName,
+                                       static_cast<const TType *>(paramType),
+                                       SymbolType::AngleInternal));
+
+    return TIntermAggregate::CreateRawFunctionCall(
+        *getInternalFunction(*roundFunctionName, roundedChild->getType(), arguments, parameters,
+                             true),
+        arguments);
+}
+
+TIntermAggregate *EmulatePrecision::createCompoundAssignmentFunctionCallNode(TIntermTyped *left,
+                                                                             TIntermTyped *right,
+                                                                             const char *opNameStr)
+{
+    std::stringstream strstr;
+    if (left->getPrecision() == EbpMedium)
+        strstr << "angle_compound_" << opNameStr << "_frm";
+    else
+        strstr << "angle_compound_" << opNameStr << "_frl";
+    ImmutableString functionName = ImmutableString(strstr.str());
+    TIntermSequence *arguments   = new TIntermSequence();
+    arguments->push_back(left);
+    arguments->push_back(right);
+
+    TVector<const TVariable *> parameters;
+    TType *leftParamType = new TType(left->getType());
+    leftParamType->setPrecision(EbpHigh);
+    leftParamType->setQualifier(EvqOut);
+    parameters.push_back(new TVariable(mSymbolTable, kParamXName,
+                                       static_cast<const TType *>(leftParamType),
+                                       SymbolType::AngleInternal));
+    TType *rightParamType = new TType(right->getType());
+    rightParamType->setPrecision(EbpHigh);
+    rightParamType->setQualifier(EvqIn);
+    parameters.push_back(new TVariable(mSymbolTable, kParamYName,
+                                       static_cast<const TType *>(rightParamType),
+                                       SymbolType::AngleInternal));
+
+    return TIntermAggregate::CreateRawFunctionCall(
+        *getInternalFunction(functionName, left->getType(), arguments, parameters, false),
+        arguments);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulatePrecision.h
@@ -0,0 +1,85 @@
+//
+// Copyright (c) 2002-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_TREEOPS_EMULATE_PRECISION_H_
+#define COMPILER_TRANSLATOR_TREEOPS_EMULATE_PRECISION_H_
+
+#include "GLSLANG/ShaderLang.h"
+#include "common/angleutils.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+// This class gathers all compound assignments from the AST and can then write
+// the functions required for their precision emulation. This way there is no
+// need to write a huge number of variations of the emulated compound assignment
+// to every translated shader with emulation enabled.
+
+namespace sh
+{
+
+class EmulatePrecision : public TLValueTrackingTraverser
+{
+  public:
+    EmulatePrecision(TSymbolTable *symbolTable);
+
+    void visitSymbol(TIntermSymbol *node) override;
+    bool visitBinary(Visit visit, TIntermBinary *node) override;
+    bool visitUnary(Visit visit, TIntermUnary *node) override;
+    bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+    bool visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node) override;
+    bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+
+    void writeEmulationHelpers(TInfoSinkBase &sink,
+                               const int shaderVersion,
+                               const ShShaderOutput outputLanguage);
+
+    static bool SupportedInLanguage(const ShShaderOutput outputLanguage);
+
+  private:
+    struct TypePair
+    {
+        TypePair(const char *l, const char *r) : lType(l), rType(r) {}
+
+        const char *lType;
+        const char *rType;
+    };
+
+    struct TypePairComparator
+    {
+        bool operator()(const TypePair &l, const TypePair &r) const
+        {
+            if (l.lType == r.lType)
+                return l.rType < r.rType;
+            return l.lType < r.lType;
+        }
+    };
+
+    const TFunction *getInternalFunction(const ImmutableString &functionName,
+                                         const TType &returnType,
+                                         TIntermSequence *arguments,
+                                         const TVector<const TVariable *> &parameters,
+                                         bool knownToNotHaveSideEffects);
+    TIntermAggregate *createRoundingFunctionCallNode(TIntermTyped *roundedChild);
+    TIntermAggregate *createCompoundAssignmentFunctionCallNode(TIntermTyped *left,
+                                                               TIntermTyped *right,
+                                                               const char *opNameStr);
+
+    typedef std::set<TypePair, TypePairComparator> EmulationSet;
+    EmulationSet mEmulateCompoundAdd;
+    EmulationSet mEmulateCompoundSub;
+    EmulationSet mEmulateCompoundMul;
+    EmulationSet mEmulateCompoundDiv;
+
+    // Map from mangled name to function.
+    TMap<ImmutableString, const TFunction *> mInternalFunctions;
+
+    bool mDeclaringVariables;
+};
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_EMULATE_PRECISION_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ExpandIntegerPowExpressions.cpp
@@ -0,0 +1,147 @@
+//
+// Copyright (c) 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/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:
+    static void Apply(TIntermNode *root, TSymbolTable *symbolTable);
+
+  private:
+    Traverser(TSymbolTable *symbolTable);
+    bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+    void nextIteration();
+
+    bool mFound = false;
+};
+
+// static
+void Traverser::Apply(TIntermNode *root, TSymbolTable *symbolTable)
+{
+    Traverser traverser(symbolTable);
+    do
+    {
+        traverser.nextIteration();
+        root->traverse(&traverser);
+        if (traverser.mFound)
+        {
+            traverser.updateTree();
+        }
+    } while (traverser.mFound);
+}
+
+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;
+    }
+
+    ASSERT(constantExponent->getBasicType() == EbtFloat);
+    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
+
+void ExpandIntegerPowExpressions(TIntermNode *root, TSymbolTable *symbolTable)
+{
+    Traverser::Apply(root, symbolTable);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ExpandIntegerPowExpressions.h
@@ -0,0 +1,29 @@
+//
+// Copyright (c) 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_EXPANDINTEGERPOWEXPRESSIONS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_EXPANDINTEGERPOWEXPRESSIONS_H_
+
+namespace sh
+{
+
+class TIntermNode;
+class TSymbolTable;
+
+void ExpandIntegerPowExpressions(TIntermNode *root, TSymbolTable *symbolTable);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_EXPANDINTEGERPOWEXPRESSIONS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.cpp
@@ -0,0 +1,116 @@
+//
+// Copyright (c) 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
+
+void FoldExpressions(TIntermBlock *root, TDiagnostics *diagnostics)
+{
+    FoldExpressionsTraverser traverser(diagnostics);
+    do
+    {
+        traverser.nextIteration();
+        root->traverse(&traverser);
+        traverser.updateTree();
+    } while (traverser.didReplace());
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.h
@@ -0,0 +1,24 @@
+//
+// Copyright (c) 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_
+
+namespace sh
+{
+
+class TIntermBlock;
+class TDiagnostics;
+
+void FoldExpressions(TIntermBlock *root, TDiagnostics *diagnostics);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_FOLDEXPRESSIONS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.cpp
@@ -0,0 +1,312 @@
+//
+// Copyright (c) 2002-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.
+//
+
+#include "compiler/translator/tree_ops/InitializeVariables.h"
+
+#include "angle_gl.h"
+#include "common/debug.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
+    {
+        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(TIntermSequence *mainBody,
+                    const InitVariableList &variables,
+                    TSymbolTable *symbolTable,
+                    int shaderVersion,
+                    const TExtensionBehavior &extensionBehavior,
+                    bool canUseLoopsToInitialize,
+                    bool highPrecisionSupported)
+{
+    for (const auto &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())
+        {
+            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
+        {
+            initializedSymbol = ReferenceGlobalVariable(tempVariableName, *symbolTable);
+        }
+        ASSERT(initializedSymbol != nullptr);
+
+        TIntermSequence *initCode = CreateInitCode(initializedSymbol, canUseLoopsToInitialize,
+                                                   highPrecisionSupported, 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);
+                    insertStatementsInParentBlock(
+                        TIntermSequence(), *CreateInitCode(symbol, mCanUseLoopsToInitialize,
+                                                           mHighPrecisionSupported, mSymbolTable));
+                }
+                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 anonymous
+
+TIntermSequence *CreateInitCode(const TIntermTyped *initializedSymbol,
+                                bool canUseLoopsToInitialize,
+                                bool highPrecisionSupported,
+                                TSymbolTable *symbolTable)
+{
+    TIntermSequence *initCode = new TIntermSequence();
+    AddZeroInitSequence(initializedSymbol, canUseLoopsToInitialize, highPrecisionSupported,
+                        initCode, symbolTable);
+    return initCode;
+}
+
+void InitializeUninitializedLocals(TIntermBlock *root,
+                                   int shaderVersion,
+                                   bool canUseLoopsToInitialize,
+                                   bool highPrecisionSupported,
+                                   TSymbolTable *symbolTable)
+{
+    InitializeLocalsTraverser traverser(shaderVersion, symbolTable, canUseLoopsToInitialize,
+                                        highPrecisionSupported);
+    root->traverse(&traverser);
+    traverser.updateTree();
+}
+
+void InitializeVariables(TIntermBlock *root,
+                         const InitVariableList &vars,
+                         TSymbolTable *symbolTable,
+                         int shaderVersion,
+                         const TExtensionBehavior &extensionBehavior,
+                         bool canUseLoopsToInitialize,
+                         bool highPrecisionSupported)
+{
+    TIntermBlock *body = FindMainBody(root);
+    InsertInitCode(body->getSequence(), vars, symbolTable, shaderVersion, extensionBehavior,
+                   canUseLoopsToInitialize, highPrecisionSupported);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.h
@@ -0,0 +1,56 @@
+//
+// Copyright (c) 2002-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.
+//
+
+#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 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.
+
+// Return 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.
+TIntermSequence *CreateInitCode(const TIntermTyped *initializedSymbol,
+                                bool canUseLoopsToInitialize,
+                                bool highPrecisionSupported,
+                                TSymbolTable *symbolTable);
+
+// Initialize all uninitialized local variables, so that undefined behavior is avoided.
+void InitializeUninitializedLocals(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.
+void InitializeVariables(TIntermBlock *root,
+                         const InitVariableList &vars,
+                         TSymbolTable *symbolTable,
+                         int shaderVersion,
+                         const TExtensionBehavior &extensionBehavior,
+                         bool canUseLoopsToInitialize,
+                         bool highPrecisionSupported);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_INITIALIZEVARIABLES_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.cpp
@@ -0,0 +1,129 @@
+//
+// Copyright (c) 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(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(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:
+    static void apply(TIntermBlock *root);
+
+  private:
+    PruneEmptyCasesTraverser();
+    bool visitSwitch(Visit visit, TIntermSwitch *node) override;
+};
+
+void PruneEmptyCasesTraverser::apply(TIntermBlock *root)
+{
+    PruneEmptyCasesTraverser prune;
+    root->traverse(&prune);
+    prune.updateTree();
+}
+
+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.push_back(NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(),
+                                                                      node, emptyReplacement));
+        }
+        return false;
+    }
+    if (lastNoOpInStatementList < statements->size())
+    {
+        statements->erase(statements->begin() + lastNoOpInStatementList, statements->end());
+    }
+
+    return true;
+}
+
+}  // namespace
+
+void PruneEmptyCases(TIntermBlock *root)
+{
+    PruneEmptyCasesTraverser::apply(root);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.h
@@ -0,0 +1,19 @@
+//
+// Copyright (c) 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_
+
+namespace sh
+{
+class TIntermBlock;
+
+void PruneEmptyCases(TIntermBlock *root);
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_PRUNEEMPTYCASES_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.cpp
@@ -0,0 +1,167 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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.
+
+#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:
+    static void apply(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;
+};
+
+void PruneNoOpsTraverser::apply(TIntermBlock *root, TSymbolTable *symbolTable)
+{
+    PruneNoOpsTraverser prune(symbolTable);
+    root->traverse(&prune);
+    prune.updateTree();
+}
+
+PruneNoOpsTraverser::PruneNoOpsTraverser(TSymbolTable *symbolTable)
+    : TIntermTraverser(true, false, false, symbolTable)
+{
+}
+
+bool PruneNoOpsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
+{
+    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.push_back(
+                    NodeReplaceWithMultipleEntry(node, declaratorSymbol, 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, ImmutableString(""), type, SymbolType::Empty);
+                queueReplacementWithParent(node, declaratorSymbol, new TIntermSymbol(variable),
+                                           OriginalNode::IS_DROPPED);
+            }
+        }
+    }
+    return false;
+}
+
+bool PruneNoOpsTraverser::visitBlock(Visit visit, TIntermBlock *node)
+{
+    TIntermSequence *statements = node->getSequence();
+
+    for (TIntermNode *statement : *statements)
+    {
+        if (IsNoOp(statement))
+        {
+            TIntermSequence emptyReplacement;
+            mMultiReplacements.push_back(
+                NodeReplaceWithMultipleEntry(node, statement, emptyReplacement));
+        }
+    }
+
+    return true;
+}
+
+bool PruneNoOpsTraverser::visitLoop(Visit visit, TIntermLoop *loop)
+{
+    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;
+}
+
+}  // namespace
+
+void PruneNoOps(TIntermBlock *root, TSymbolTable *symbolTable)
+{
+    PruneNoOpsTraverser::apply(root, symbolTable);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.h
@@ -0,0 +1,25 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_PRUNENOOPS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_PRUNENOOPS_H_
+
+namespace sh
+{
+class TIntermBlock;
+class TSymbolTable;
+
+void PruneNoOps(TIntermBlock *root, TSymbolTable *symbolTable);
+}
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_PRUNENOOPS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.cpp
@@ -0,0 +1,168 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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;
+
+    void nextIteration();
+
+    bool foundHigherPrecisionConstant() const { return mFoundHigherPrecisionConstant; }
+
+  protected:
+    bool operandAffectsParentOperationPrecision(TIntermTyped *operand);
+
+    bool mFoundHigherPrecisionConstant;
+};
+
+RecordConstantPrecisionTraverser::RecordConstantPrecisionTraverser(TSymbolTable *symbolTable)
+    : TIntermTraverser(true, false, true, symbolTable), mFoundHigherPrecisionConstant(false)
+{
+}
+
+bool RecordConstantPrecisionTraverser::operandAffectsParentOperationPrecision(TIntermTyped *operand)
+{
+    if (getParentNode()->getAsCaseNode() || getParentNode()->getAsBlock())
+    {
+        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:
+                break;
+        }
+
+        TIntermTyped *otherOperand = parentAsBinary->getRight();
+        if (otherOperand == operand)
+        {
+            otherOperand = parentAsBinary->getLeft();
+        }
+        // If the precision of the other child is at least as high as the precision of the constant,
+        // the precision of the constant has no effect.
+        if (otherOperand->getAsConstantUnion() == nullptr &&
+            otherOperand->getPrecision() >= operand->getPrecision())
+        {
+            return false;
+        }
+    }
+
+    TIntermAggregate *parentAsAggregate = getParentNode()->getAsAggregate();
+    if (parentAsAggregate != nullptr)
+    {
+        if (!parentAsAggregate->gotPrecisionFromChildren())
+        {
+            // This can be either:
+            // * a call to an user-defined function
+            // * a call to a texture function
+            // * some other kind of aggregate
+            // In any of these cases the constant precision has no effect.
+            return false;
+        }
+        if (parentAsAggregate->isConstructor() && parentAsAggregate->getBasicType() == EbtBool)
+        {
+            return false;
+        }
+        // If the precision of operands does affect the result, but the precision of any of the
+        // other children has a precision that's at least as high as the precision of the constant,
+        // the precision of the constant has no effect.
+        TIntermSequence *parameters = parentAsAggregate->getSequence();
+        for (TIntermNode *parameter : *parameters)
+        {
+            const TIntermTyped *typedParameter = parameter->getAsTyped();
+            if (parameter != operand && typedParameter != nullptr &&
+                parameter->getAsConstantUnion() == nullptr &&
+                typedParameter->getPrecision() >= operand->getPrecision())
+            {
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+void RecordConstantPrecisionTraverser::visitConstantUnion(TIntermConstantUnion *node)
+{
+    if (mFoundHigherPrecisionConstant)
+        return;
+
+    // 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);
+    mFoundHigherPrecisionConstant = true;
+}
+
+void RecordConstantPrecisionTraverser::nextIteration()
+{
+    mFoundHigherPrecisionConstant = false;
+}
+
+}  // namespace
+
+void RecordConstantPrecision(TIntermNode *root, TSymbolTable *symbolTable)
+{
+    RecordConstantPrecisionTraverser traverser(symbolTable);
+    // Iterate as necessary, and reset the traverser between iterations.
+    do
+    {
+        traverser.nextIteration();
+        root->traverse(&traverser);
+        if (traverser.foundHigherPrecisionConstant())
+            traverser.updateTree();
+    } while (traverser.foundHigherPrecisionConstant());
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.h
@@ -0,0 +1,28 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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_
+
+namespace sh
+{
+class TIntermNode;
+class TSymbolTable;
+
+void RecordConstantPrecision(TIntermNode *root, TSymbolTable *symbolTable);
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_RECORDCONSTANTPRECISION_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RegenerateStructNames.cpp
@@ -0,0 +1,87 @@
+//
+// Copyright (c) 2002-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/tree_ops/RegenerateStructNames.h"
+
+#include "common/debug.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+
+namespace sh
+{
+
+namespace
+{
+constexpr const ImmutableString kPrefix("_webgl_struct_");
+}  // anonymous namespace
+
+void RegenerateStructNames::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 RegenerateStructNames::visitBlock(Visit, TIntermBlock *block)
+{
+    ++mScopeDepth;
+    TIntermSequence &sequence = *(block->getSequence());
+    for (TIntermNode *node : sequence)
+    {
+        node->traverse(this);
+    }
+    --mScopeDepth;
+    return false;
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RegenerateStructNames.h
@@ -0,0 +1,41 @@
+//
+// Copyright (c) 2002-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_TREEOPS_REGENERATESTRUCTNAMES_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REGENERATESTRUCTNAMES_H_
+
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+#include <set>
+
+namespace sh
+{
+
+class RegenerateStructNames : public TIntermTraverser
+{
+  public:
+    RegenerateStructNames(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's declared globally, push its ID in this set.
+    std::set<int> mDeclaredGlobalStructs;
+};
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_REGENERATESTRUCTNAMES_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.cpp
@@ -0,0 +1,83 @@
+//
+// Copyright (c) 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:
+    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;
+        if (!node->getOperand()->hasSideEffects())
+        {
+            queueReplacement(node->fold(nullptr), OriginalNode::IS_DROPPED);
+            return false;
+        }
+        insertStatementInParentBlock(node->getOperand()->deepCopy());
+        TConstantUnion *constArray = new TConstantUnion[1];
+        constArray->setIConst(node->getOperand()->getOutermostArraySize());
+        queueReplacement(new TIntermConstantUnion(constArray, node->getType()),
+                         OriginalNode::IS_DROPPED);
+        return false;
+    }
+    return true;
+}
+
+}  // anonymous namespace
+
+void RemoveArrayLengthMethod(TIntermBlock *root)
+{
+    RemoveArrayLengthTraverser traverser;
+    do
+    {
+        traverser.nextIteration();
+        root->traverse(&traverser);
+        if (traverser.foundArrayLength())
+            traverser.updateTree();
+    } while (traverser.foundArrayLength());
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.h
@@ -0,0 +1,34 @@
+//
+// Copyright (c) 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_
+
+namespace sh
+{
+
+class TIntermBlock;
+
+void RemoveArrayLengthMethod(TIntermBlock *root);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_REMOVEARRAYLENGTHMETHOD_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.cpp
@@ -0,0 +1,542 @@
+//
+// Copyright (c) 2002-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.
+//
+// RemoveDynamicIndexing is an AST traverser to remove dynamic indexing of vectors and matrices,
+// replacing them with calls to functions that choose which component to return or write.
+//
+
+#include "compiler/translator/tree_ops/RemoveDynamicIndexing.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
+{
+
+const TType *kIndexType = StaticType::Get<EbtInt, EbpHigh, EvqIn, 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" << type.getCols() << "x" << 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 << 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 = new TIntermSequence();
+    arguments->push_back(node);
+    return TIntermAggregate::CreateConstructor(TType(EbtInt), arguments);
+}
+
+TType *GetFieldType(const TType &indexedType)
+{
+    if (indexedType.isMatrix())
+    {
+        TType *fieldType = new TType(indexedType.getBasicType(), indexedType.getPrecision());
+        fieldType->setPrimarySize(static_cast<unsigned char>(indexedType.getRows()));
+        return fieldType;
+    }
+    else
+    {
+        return new TType(indexedType.getBasicType(), indexedType.getPrecision());
+    }
+}
+
+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(EvqInOut);
+    if (!write)
+        baseType->setQualifier(EvqIn);
+    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());
+
+    int 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 (int 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(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;
+
+    PerformanceDiagnostics *mPerfDiagnostics;
+};
+
+RemoveDynamicIndexingTraverser::RemoveDynamicIndexingTraverser(
+    TSymbolTable *symbolTable,
+    PerformanceDiagnostics *perfDiagnostics)
+    : TLValueTrackingTraverser(true, false, false, symbolTable),
+      mUsedTreeInsertion(false),
+      mRemoveIndexSideEffectsInSubtree(false),
+      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 = new TIntermSequence();
+    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 = new TIntermSequence();
+    // 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 (IntermNodePatternMatcher::IsDynamicIndexingOfVectorOrMatrix(node))
+        {
+            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 &&
+                    IntermNodePatternMatcher::IsDynamicIndexingOfVectorOrMatrix(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>(), 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(EvqIn);
+                    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;
+}
+
+}  // namespace
+
+void RemoveDynamicIndexing(TIntermNode *root,
+                           TSymbolTable *symbolTable,
+                           PerformanceDiagnostics *perfDiagnostics)
+{
+    RemoveDynamicIndexingTraverser traverser(symbolTable, perfDiagnostics);
+    do
+    {
+        traverser.nextIteration();
+        root->traverse(&traverser);
+        traverser.updateTree();
+    } 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);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.h
@@ -0,0 +1,26 @@
+//
+// Copyright (c) 2002-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.
+//
+// RemoveDynamicIndexing is an AST traverser to remove dynamic indexing of vectors and matrices,
+// replacing them with calls to functions that choose which component to return or write.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REMOVEDYNAMICINDEXING_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REMOVEDYNAMICINDEXING_H_
+
+namespace sh
+{
+
+class TIntermNode;
+class TSymbolTable;
+class PerformanceDiagnostics;
+
+void RemoveDynamicIndexing(TIntermNode *root,
+                           TSymbolTable *symbolTable,
+                           PerformanceDiagnostics *perfDiagnostics);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_REMOVEDYNAMICINDEXING_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.cpp
@@ -0,0 +1,43 @@
+//
+// Copyright (c) 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 visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node) override
+    {
+        TIntermSequence emptyReplacement;
+        mMultiReplacements.push_back(
+            NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(), node, emptyReplacement));
+        return false;
+    }
+};
+
+}  // anonymous namespace
+
+void RemoveInvariantDeclaration(TIntermNode *root)
+{
+    RemoveInvariantDeclarationTraverser traverser;
+    root->traverse(&traverser);
+    traverser.updateTree();
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.h
@@ -0,0 +1,18 @@
+//
+// Copyright (c) 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_
+
+class TIntermNode;
+namespace sh
+{
+
+void RemoveInvariantDeclaration(TIntermNode *root);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_REMOVEINVARIANTDECLARATION_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemovePow.cpp
@@ -0,0 +1,102 @@
+//
+// Copyright (c) 2002-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.
+//
+// RemovePow is an AST traverser to convert pow(x, y) built-in calls where y is a
+// constant to exp2(y * log2(x)). This works around an issue in NVIDIA 311 series
+// OpenGL drivers.
+//
+
+#include "compiler/translator/tree_ops/RemovePow.h"
+
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+bool IsProblematicPow(TIntermTyped *node)
+{
+    TIntermAggregate *agg = node->getAsAggregate();
+    if (agg != nullptr && agg->getOp() == EOpPow)
+    {
+        ASSERT(agg->getSequence()->size() == 2);
+        return agg->getSequence()->at(1)->getAsConstantUnion() != nullptr;
+    }
+    return false;
+}
+
+// Traverser that converts all pow operations simultaneously.
+class RemovePowTraverser : public TIntermTraverser
+{
+  public:
+    RemovePowTraverser(TSymbolTable *symbolTable);
+
+    bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+
+    void nextIteration() { mNeedAnotherIteration = false; }
+    bool needAnotherIteration() const { return mNeedAnotherIteration; }
+
+  protected:
+    bool mNeedAnotherIteration;
+};
+
+RemovePowTraverser::RemovePowTraverser(TSymbolTable *symbolTable)
+    : TIntermTraverser(true, false, false, symbolTable), mNeedAnotherIteration(false)
+{
+}
+
+bool RemovePowTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+    if (IsProblematicPow(node))
+    {
+        TIntermTyped *x = node->getSequence()->at(0)->getAsTyped();
+        TIntermTyped *y = node->getSequence()->at(1)->getAsTyped();
+
+        TIntermSequence *logArgs = new TIntermSequence();
+        logArgs->push_back(x);
+        TIntermTyped *log = CreateBuiltInFunctionCallNode("log2", logArgs, *mSymbolTable, 100);
+        log->setLine(node->getLine());
+
+        TOperator op       = TIntermBinary::GetMulOpBasedOnOperands(y->getType(), log->getType());
+        TIntermBinary *mul = new TIntermBinary(op, y, log);
+        mul->setLine(node->getLine());
+
+        TIntermSequence *expArgs = new TIntermSequence();
+        expArgs->push_back(mul);
+        TIntermTyped *exp = CreateBuiltInFunctionCallNode("exp2", expArgs, *mSymbolTable, 100);
+        exp->setLine(node->getLine());
+
+        queueReplacement(exp, OriginalNode::IS_DROPPED);
+
+        // If the x parameter also needs to be replaced, we need to do that in another traversal,
+        // since it's parent node will change in a way that's not handled correctly by updateTree().
+        if (IsProblematicPow(x))
+        {
+            mNeedAnotherIteration = true;
+            return false;
+        }
+    }
+    return true;
+}
+
+}  // namespace
+
+void RemovePow(TIntermNode *root, TSymbolTable *symbolTable)
+{
+    RemovePowTraverser traverser(symbolTable);
+    // Iterate as necessary, and reset the traverser between iterations.
+    do
+    {
+        traverser.nextIteration();
+        root->traverse(&traverser);
+        traverser.updateTree();
+    } while (traverser.needAnotherIteration());
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemovePow.h
@@ -0,0 +1,22 @@
+//
+// Copyright (c) 2002-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.
+//
+// RemovePow is an AST traverser to convert pow(x, y) built-in calls where y is a
+// constant to exp2(y * log2(x)). This works around an issue in NVIDIA 311 series
+// OpenGL drivers.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REMOVEPOW_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REMOVEPOW_H_
+
+namespace sh
+{
+class TIntermNode;
+class TSymbolTable;
+
+void RemovePow(TIntermNode *root, TSymbolTable *symbolTable);
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_REMOVEPOW_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveSwitchFallThrough.cpp
@@ -0,0 +1,270 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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/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
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveSwitchFallThrough.h
@@ -0,0 +1,27 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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_REMOVESWITCHFALLTHROUGH_H_
+#define COMPILER_TRANSLATOR_TREEOPS_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_REMOVESWITCHFALLTHROUGH_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.cpp
@@ -0,0 +1,373 @@
+//
+// Copyright (c) 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 = std::unordered_map<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, ImmutableString(""), new TType(declarator->getType()),
+                              SymbolType::Empty);
+            queueReplacementWithParent(node, declarator, new TIntermSymbol(emptyVariable),
+                                       OriginalNode::IS_DROPPED);
+            return;
+        }
+    }
+
+    if (getParentNode()->getAsBlock())
+    {
+        TIntermSequence emptyReplacement;
+        mMultiReplacements.push_back(
+            NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(), node, 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
+
+void RemoveUnreferencedVariables(TIntermBlock *root, TSymbolTable *symbolTable)
+{
+    CollectVariableRefCountsTraverser collector;
+    root->traverse(&collector);
+    RemoveUnreferencedVariablesTraverser traverser(&collector.getSymbolIdRefCounts(),
+                                                   &collector.getStructIdRefCounts(), symbolTable);
+    root->traverse(&traverser);
+    traverser.updateTree();
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.h
@@ -0,0 +1,24 @@
+//
+// Copyright (c) 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_
+
+namespace sh
+{
+
+class TIntermBlock;
+class TSymbolTable;
+
+void RemoveUnreferencedVariables(TIntermBlock *root, TSymbolTable *symbolTable);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_REMOVEUNREFERENCEDVARIABLES_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDoWhile.cpp
@@ -0,0 +1,145 @@
+//
+// Copyright (c) 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/RewriteDoWhile.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
+
+void RewriteDoWhile(TIntermNode *root, TSymbolTable *symbolTable)
+{
+    DoWhileRewriter rewriter(symbolTable);
+
+    root->traverse(&rewriter);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDoWhile.h
@@ -0,0 +1,23 @@
+//
+// Copyright (c) 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_REWRITEDOWHILE_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITEDOWHILE_H_
+
+namespace sh
+{
+
+class TIntermNode;
+class TSymbolTable;
+
+void RewriteDoWhile(TIntermNode *root, TSymbolTable *symbolTable);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_REWRITEDOWHILE_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteElseBlocks.cpp
@@ -0,0 +1,121 @@
+//
+// Copyright (c) 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/RewriteElseBlocks.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 dummy
+        // 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
+
+void RewriteElseBlocks(TIntermNode *node, TSymbolTable *symbolTable)
+{
+    ElseBlockRewriter rewriter(symbolTable);
+    node->traverse(&rewriter);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteElseBlocks.h
@@ -0,0 +1,22 @@
+//
+// Copyright (c) 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_REWRITEELSEBLOCKS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITEELSEBLOCKS_H_
+
+namespace sh
+{
+
+class TIntermNode;
+class TSymbolTable;
+
+void RewriteElseBlocks(TIntermNode *node, TSymbolTable *symbolTable);
+}
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_REWRITEELSEBLOCKS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.cpp
@@ -0,0 +1,155 @@
+//
+// Copyright (c) 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:
+    static void Apply(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
+void Traverser::Apply(TIntermNode *root, const TSymbolTable &symbolTable, int shaderVersion)
+{
+    Traverser traverser(symbolTable, shaderVersion);
+    do
+    {
+        traverser.nextIteration();
+        root->traverse(&traverser);
+        if (traverser.mFound)
+        {
+            traverser.updateTree();
+        }
+    } while (traverser.mFound);
+}
+
+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 (node->getOp() != EOpCallBuiltInFunction)
+    {
+        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 = new TIntermSequence();
+
+    // 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 = new TIntermSequence();
+        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
+
+void RewriteTexelFetchOffset(TIntermNode *root, const TSymbolTable &symbolTable, int shaderVersion)
+{
+    // texelFetchOffset is only valid in GLSL 3.0 and later.
+    if (shaderVersion < 300)
+        return;
+
+    Traverser::Apply(root, symbolTable, shaderVersion);
+}
+
+}  // namespace sh
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.h
@@ -0,0 +1,28 @@
+//
+// Copyright (c) 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_
+
+class TIntermNode;
+class TSymbolTable;
+
+namespace sh
+{
+
+void RewriteTexelFetchOffset(TIntermNode *root, const TSymbolTable &symbolTable, int shaderVersion);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_REWRITE_TEXELFETCHOFFSET_H_
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteUnaryMinusOperatorFloat.cpp
@@ -0,0 +1,94 @@
+//
+// Copyright (c) 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/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:
+    static void Apply(TIntermNode *root);
+
+  private:
+    Traverser();
+    bool visitUnary(Visit visit, TIntermUnary *node) override;
+    void nextIteration();
+
+    bool mFound = false;
+};
+
+// static
+void Traverser::Apply(TIntermNode *root)
+{
+    Traverser traverser;
+    do
+    {
+        traverser.nextIteration();
+        root->traverse(&traverser);
+        if (traverser.mFound)
+        {
+            traverser.updateTree();
+        }
+    } while (traverser.mFound);
+}
+
+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
+
+void RewriteUnaryMinusOperatorFloat(TIntermNode *root)
+{
+    Traverser::Apply(root);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteUnaryMinusOperatorFloat.h
@@ -0,0 +1,19 @@
+// Copyright (c) 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_REWRITEUNARYMINUSOPERATORFLOAT_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITEUNARYMINUSOPERATORFLOAT_H_
+
+class TIntermNode;
+namespace sh
+{
+
+void RewriteUnaryMinusOperatorFloat(TIntermNode *root);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_REWRITEUNARYMINUSOPERATORFLOAT_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteUnaryMinusOperatorInt.cpp
@@ -0,0 +1,112 @@
+//
+// Copyright (c) 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/RewriteUnaryMinusOperatorInt.h"
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class Traverser : public TIntermTraverser
+{
+  public:
+    static void Apply(TIntermNode *root);
+
+  private:
+    Traverser();
+    bool visitUnary(Visit visit, TIntermUnary *node) override;
+    void nextIteration();
+
+    bool mFound = false;
+};
+
+// static
+void Traverser::Apply(TIntermNode *root)
+{
+    Traverser traverser;
+    do
+    {
+        traverser.nextIteration();
+        root->traverse(&traverser);
+        if (traverser.mFound)
+        {
+            traverser.updateTree();
+        }
+    } while (traverser.mFound);
+}
+
+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);
+    }
+    TIntermConstantUnion *oneNode =
+        new TIntermConstantUnion(one, TType(opr->getBasicType(), opr->getPrecision(), EvqConst));
+    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
+
+void RewriteUnaryMinusOperatorInt(TIntermNode *root)
+{
+    Traverser::Apply(root);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteUnaryMinusOperatorInt.h
@@ -0,0 +1,20 @@
+// Copyright (c) 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_REWRITEUNARYMINUSOPERATORINT_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITEUNARYMINUSOPERATORINT_H_
+
+class TIntermNode;
+namespace sh
+{
+
+void RewriteUnaryMinusOperatorInt(TIntermNode *root);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_REWRITEUNARYMINUSOPERATORINT_H_
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.cpp
@@ -0,0 +1,227 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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/tree_util/IntermNodePatternMatcher.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+TIntermBinary *ConstructVectorIndexBinaryNode(TIntermSymbol *symbolNode, int index)
+{
+    return new TIntermBinary(EOpIndexDirect, symbolNode, CreateIndexNode(index));
+}
+
+TIntermBinary *ConstructMatrixIndexBinaryNode(TIntermSymbol *symbolNode, int colIndex, int rowIndex)
+{
+    TIntermBinary *colVectorNode = ConstructVectorIndexBinaryNode(symbolNode, colIndex);
+
+    return new TIntermBinary(EOpIndexDirect, colVectorNode, CreateIndexNode(rowIndex));
+}
+
+class ScalarizeArgsTraverser : public TIntermTraverser
+{
+  public:
+    ScalarizeArgsTraverser(sh::GLenum shaderType,
+                           bool fragmentPrecisionHigh,
+                           TSymbolTable *symbolTable)
+        : TIntermTraverser(true, false, false, symbolTable),
+          mShaderType(shaderType),
+          mFragmentPrecisionHigh(fragmentPrecisionHigh),
+          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.
+    TVariable *createTempVariable(TIntermTyped *original);
+
+    std::vector<TIntermSequence> mBlockStack;
+
+    sh::GLenum mShaderType;
+    bool mFragmentPrecisionHigh;
+
+    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);
+        TVariable *argVariable = createTempVariable(originalArg);
+        if (originalArg->isScalar())
+        {
+            sequence->push_back(CreateTempSymbolNode(argVariable));
+            size--;
+        }
+        else if (originalArg->isVector())
+        {
+            if (scalarizeVector)
+            {
+                int repeat = std::min(size, originalArg->getNominalSize());
+                size -= repeat;
+                for (int index = 0; index < repeat; ++index)
+                {
+                    TIntermSymbol *symbolNode = CreateTempSymbolNode(argVariable);
+                    TIntermBinary *newNode    = ConstructVectorIndexBinaryNode(symbolNode, index);
+                    sequence->push_back(newNode);
+                }
+            }
+            else
+            {
+                TIntermSymbol *symbolNode = CreateTempSymbolNode(argVariable);
+                sequence->push_back(symbolNode);
+                size -= originalArg->getNominalSize();
+            }
+        }
+        else
+        {
+            ASSERT(originalArg->isMatrix());
+            if (scalarizeMatrix)
+            {
+                int colIndex = 0, rowIndex = 0;
+                int repeat = std::min(size, originalArg->getCols() * originalArg->getRows());
+                size -= repeat;
+                while (repeat > 0)
+                {
+                    TIntermSymbol *symbolNode = CreateTempSymbolNode(argVariable);
+                    TIntermBinary *newNode =
+                        ConstructMatrixIndexBinaryNode(symbolNode, colIndex, rowIndex);
+                    sequence->push_back(newNode);
+                    rowIndex++;
+                    if (rowIndex >= originalArg->getRows())
+                    {
+                        rowIndex = 0;
+                        colIndex++;
+                    }
+                    repeat--;
+                }
+            }
+            else
+            {
+                TIntermSymbol *symbolNode = CreateTempSymbolNode(argVariable);
+                sequence->push_back(symbolNode);
+                size -= originalArg->getCols() * originalArg->getRows();
+            }
+        }
+    }
+}
+
+TVariable *ScalarizeArgsTraverser::createTempVariable(TIntermTyped *original)
+{
+    ASSERT(original);
+
+    TType *type = new TType(original->getType());
+    type->setQualifier(EvqTemporary);
+    if (mShaderType == GL_FRAGMENT_SHADER && type->getBasicType() == EbtFloat &&
+        type->getPrecision() == EbpUndefined)
+    {
+        // We use the highest available precision for the temporary variable
+        // to avoid computing the actual precision using the rules defined
+        // in GLSL ES 1.0 Section 4.5.2.
+        type->setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
+    }
+
+    TVariable *variable = CreateTempVariable(mSymbolTable, type);
+
+    ASSERT(mBlockStack.size() > 0);
+    TIntermSequence &sequence       = mBlockStack.back();
+    TIntermDeclaration *declaration = CreateTempInitDeclarationNode(variable, original);
+    sequence.push_back(declaration);
+
+    return variable;
+}
+
+}  // namespace anonymous
+
+void ScalarizeVecAndMatConstructorArgs(TIntermBlock *root,
+                                       sh::GLenum shaderType,
+                                       bool fragmentPrecisionHigh,
+                                       TSymbolTable *symbolTable)
+{
+    ScalarizeArgsTraverser scalarizer(shaderType, fragmentPrecisionHigh, symbolTable);
+    root->traverse(&scalarizer);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.h
@@ -0,0 +1,27 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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"
+
+namespace sh
+{
+class TIntermBlock;
+class TSymbolTable;
+
+void ScalarizeVecAndMatConstructorArgs(TIntermBlock *root,
+                                       sh::GLenum shaderType,
+                                       bool fragmentPrecisionHigh,
+                                       TSymbolTable *symbolTable);
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_SCALARIZEVECANDMATCONSTRUCTORARGS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateArrayConstructorStatements.cpp
@@ -0,0 +1,85 @@
+//
+// Copyright (c) 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/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.push_back(
+        NodeReplaceWithMultipleEntry(parentAsBlock, node, constructorArgs));
+
+    return false;
+}
+
+}  // namespace
+
+void SeparateArrayConstructorStatements(TIntermBlock *root)
+{
+    SeparateArrayConstructorStatementsTraverser traverser;
+    root->traverse(&traverser);
+    traverser.updateTree();
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateArrayConstructorStatements.h
@@ -0,0 +1,22 @@
+//
+// Copyright (c) 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_SEPARATEARRAYCONSTRUCTORSTATEMENTS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_SEPARATEARRAYCONSTRUCTORSTATEMENTS_H_
+
+namespace sh
+{
+class TIntermBlock;
+
+void SeparateArrayConstructorStatements(TIntermBlock *root);
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_SEPARATEARRAYCONSTRUCTORSTATEMENTS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateArrayInitialization.cpp
@@ -0,0 +1,92 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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/SeparateArrayInitialization.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/OutputHLSL.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class SeparateArrayInitTraverser : private TIntermTraverser
+{
+  public:
+    static void apply(TIntermNode *root);
+
+  private:
+    SeparateArrayInitTraverser();
+    bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+};
+
+void SeparateArrayInitTraverser::apply(TIntermNode *root)
+{
+    SeparateArrayInitTraverser separateInit;
+    root->traverse(&separateInit);
+    separateInit.updateTree();
+}
+
+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.push_back(
+                NodeReplaceWithMultipleEntry(parentBlock, node, replacements));
+        }
+    }
+    return false;
+}
+
+}  // namespace
+
+void SeparateArrayInitialization(TIntermNode *root)
+{
+    SeparateArrayInitTraverser::apply(root);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateArrayInitialization.h
@@ -0,0 +1,29 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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_SEPARATEARRAYINITIALIZATION_H_
+#define COMPILER_TRANSLATOR_TREEOPS_SEPARATEARRAYINITIALIZATION_H_
+
+namespace sh
+{
+class TIntermNode;
+
+void SeparateArrayInitialization(TIntermNode *root);
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_SEPARATEARRAYINITIALIZATION_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.cpp
@@ -0,0 +1,79 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class SeparateDeclarationsTraverser : private TIntermTraverser
+{
+  public:
+    static void apply(TIntermNode *root);
+
+  private:
+    SeparateDeclarationsTraverser();
+    bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+};
+
+void SeparateDeclarationsTraverser::apply(TIntermNode *root)
+{
+    SeparateDeclarationsTraverser separateDecl;
+    root->traverse(&separateDecl);
+    separateDecl.updateTree();
+}
+
+SeparateDeclarationsTraverser::SeparateDeclarationsTraverser()
+    : TIntermTraverser(true, false, false)
+{
+}
+
+bool SeparateDeclarationsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
+{
+    TIntermSequence *sequence = node->getSequence();
+    if (sequence->size() > 1)
+    {
+        TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+        ASSERT(parentBlock != nullptr);
+
+        TIntermSequence replacementDeclarations;
+        for (size_t ii = 0; ii < sequence->size(); ++ii)
+        {
+            TIntermDeclaration *replacementDeclaration = new TIntermDeclaration();
+
+            replacementDeclaration->appendDeclarator(sequence->at(ii)->getAsTyped());
+            replacementDeclaration->setLine(sequence->at(ii)->getLine());
+            replacementDeclarations.push_back(replacementDeclaration);
+        }
+
+        mMultiReplacements.push_back(
+            NodeReplaceWithMultipleEntry(parentBlock, node, replacementDeclarations));
+    }
+    return false;
+}
+
+}  // namespace
+
+void SeparateDeclarations(TIntermNode *root)
+{
+    SeparateDeclarationsTraverser::apply(root);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.h
@@ -0,0 +1,26 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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_
+
+namespace sh
+{
+class TIntermNode;
+
+void SeparateDeclarations(TIntermNode *root);
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_SEPARATEDECLARATIONS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateExpressionsReturningArrays.cpp
@@ -0,0 +1,130 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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/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
+
+void SeparateExpressionsReturningArrays(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())
+            traverser.updateTree();
+    } while (traverser.foundArrayExpression());
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateExpressionsReturningArrays.h
@@ -0,0 +1,23 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_
+
+namespace sh
+{
+class TIntermNode;
+class TSymbolTable;
+
+void SeparateExpressionsReturningArrays(TIntermNode *root, TSymbolTable *symbolTable);
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.cpp
@@ -0,0 +1,300 @@
+//
+// Copyright (c) 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
+{
+
+class SimplifyLoopConditionsTraverser : public TLValueTrackingTraverser
+{
+  public:
+    SimplifyLoopConditionsTraverser(unsigned int conditionsToSimplifyMask,
+                                    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 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;
+    IntermNodePatternMatcher mConditionsToSimplify;
+};
+
+SimplifyLoopConditionsTraverser::SimplifyLoopConditionsTraverser(
+    unsigned int conditionsToSimplifyMask,
+    TSymbolTable *symbolTable)
+    : TLValueTrackingTraverser(true, false, false, symbolTable),
+      mFoundLoopToChange(false),
+      mInsideLoopInitConditionOrExpression(false),
+      mConditionsToSimplify(conditionsToSimplifyMask)
+{
+}
+
+// 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.
+
+    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.
+
+    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.
+
+    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.
+
+    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.
+
+    mFoundLoopToChange = mConditionsToSimplify.match(node);
+    return !mFoundLoopToChange;
+}
+
+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                   = false;
+
+    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;
+
+    if (mFoundLoopToChange)
+    {
+        const TType *boolType        = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
+        TVariable *conditionVariable = CreateTempVariable(mSymbolTable, boolType);
+
+        // Replace the loop condition with a boolean variable that's updated on each iteration.
+        TLoopType loopType = node->getType();
+        if (loopType == ELoopWhile)
+        {
+            // Transform:
+            //   while (expr) { body; }
+            // into
+            //   bool s0 = expr;
+            //   while (s0) { { body; } s0 = expr; }
+            TIntermDeclaration *tempInitDeclaration =
+                CreateTempInitDeclarationNode(conditionVariable, node->getCondition()->deepCopy());
+            insertStatementInParentBlock(tempInitDeclaration);
+
+            TIntermBlock *newBody = new TIntermBlock();
+            if (node->getBody())
+            {
+                newBody->getSequence()->push_back(node->getBody());
+            }
+            newBody->getSequence()->push_back(
+                CreateTempAssignmentNode(conditionVariable, node->getCondition()->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(conditionVariable));
+        }
+        else if (loopType == ELoopDoWhile)
+        {
+            // Transform:
+            //   do {
+            //     body;
+            //   } while (expr);
+            // into
+            //   bool s0 = true;
+            //   do {
+            //     { body; }
+            //     s0 = expr;
+            //   } while (s0);
+            TIntermDeclaration *tempInitDeclaration =
+                CreateTempInitDeclarationNode(conditionVariable, CreateBoolNode(true));
+            insertStatementInParentBlock(tempInitDeclaration);
+
+            TIntermBlock *newBody = new TIntermBlock();
+            if (node->getBody())
+            {
+                newBody->getSequence()->push_back(node->getBody());
+            }
+            newBody->getSequence()->push_back(
+                CreateTempAssignmentNode(conditionVariable, node->getCondition()->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(conditionVariable));
+        }
+        else if (loopType == ELoopFor)
+        {
+            // Move the loop condition inside the loop.
+            // Transform:
+            //   for (init; expr; exprB) { body; }
+            // into
+            //   {
+            //     init;
+            //     bool s0 = expr;
+            //     while (s0) {
+            //       { body; }
+            //       exprB;
+            //       s0 = expr;
+            //     }
+            //   }
+            TIntermBlock *loopScope            = new TIntermBlock();
+            TIntermSequence *loopScopeSequence = loopScope->getSequence();
+
+            // Insert "init;"
+            if (node->getInit())
+            {
+                loopScopeSequence->push_back(node->getInit());
+            }
+
+            // Insert "bool s0 = expr;" if applicable, "bool s0 = true;" otherwise
+            TIntermTyped *conditionInitializer = nullptr;
+            if (node->getCondition())
+            {
+                conditionInitializer = node->getCondition()->deepCopy();
+            }
+            else
+            {
+                conditionInitializer = CreateBoolNode(true);
+            }
+            loopScopeSequence->push_back(
+                CreateTempInitDeclarationNode(conditionVariable, conditionInitializer));
+
+            // Insert "{ body; }" in the while loop
+            TIntermBlock *whileLoopBody = new TIntermBlock();
+            if (node->getBody())
+            {
+                whileLoopBody->getSequence()->push_back(node->getBody());
+            }
+            // Insert "exprB;" in the while loop
+            if (node->getExpression())
+            {
+                whileLoopBody->getSequence()->push_back(node->getExpression());
+            }
+            // Insert "s0 = expr;" in the while loop
+            if (node->getCondition())
+            {
+                whileLoopBody->getSequence()->push_back(
+                    CreateTempAssignmentNode(conditionVariable, node->getCondition()->deepCopy()));
+            }
+
+            // Create "while(s0) { whileLoopBody }"
+            TIntermLoop *whileLoop =
+                new TIntermLoop(ELoopWhile, nullptr, CreateTempSymbolNode(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);
+}
+
+}  // namespace
+
+void SimplifyLoopConditions(TIntermNode *root,
+                            unsigned int conditionsToSimplifyMask,
+                            TSymbolTable *symbolTable)
+{
+    SimplifyLoopConditionsTraverser traverser(conditionsToSimplifyMask, symbolTable);
+    root->traverse(&traverser);
+    traverser.updateTree();
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.h
@@ -0,0 +1,24 @@
+//
+// Copyright (c) 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_
+
+namespace sh
+{
+class TIntermNode;
+class TSymbolTable;
+
+void SimplifyLoopConditions(TIntermNode *root,
+                            unsigned int conditionsToSimplify,
+                            TSymbolTable *symbolTable);
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_SIMPLIFYLOOPCONDITIONS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.cpp
@@ -0,0 +1,164 @@
+//
+// Copyright (c) 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
+
+void SplitSequenceOperator(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())
+            traverser.updateTree();
+    } while (traverser.foundExpressionToSplit());
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.h
@@ -0,0 +1,25 @@
+//
+// Copyright (c) 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_
+
+namespace sh
+{
+
+class TIntermNode;
+class TSymbolTable;
+
+void SplitSequenceOperator(TIntermNode *root, int patternsToSplitMask, TSymbolTable *symbolTable);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_SPLITSEQUENCEOPERATOR_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/UnfoldShortCircuitAST.cpp
@@ -0,0 +1,74 @@
+//
+// Copyright (c) 2002-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.
+//
+
+#include "compiler/translator/tree_ops/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
+
+void UnfoldShortCircuitAST(TIntermBlock *root)
+{
+    UnfoldShortCircuitASTTraverser traverser;
+    root->traverse(&traverser);
+    traverser.updateTree();
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/UnfoldShortCircuitAST.h
@@ -0,0 +1,22 @@
+//
+// Copyright (c) 2002-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.
+//
+// UnfoldShortCircuitAST is an AST traverser to replace short-circuiting
+// operations with ternary operations.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_UNFOLDSHORTCIRCUITAST_H_
+#define COMPILER_TRANSLATOR_TREEOPS_UNFOLDSHORTCIRCUITAST_H_
+
+namespace sh
+{
+
+class TIntermBlock;
+
+void UnfoldShortCircuitAST(TIntermBlock *root);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_UNFOLDSHORTCIRCUITAST_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/UnfoldShortCircuitToIf.cpp
@@ -0,0 +1,194 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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/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
+
+void UnfoldShortCircuitToIf(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())
+            traverser.updateTree();
+    } while (traverser.foundShortCircuit());
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/UnfoldShortCircuitToIf.h
@@ -0,0 +1,25 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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_UNFOLDSHORTCIRCUIT_H_
+#define COMPILER_TRANSLATOR_TREEOPS_UNFOLDSHORTCIRCUIT_H_
+
+namespace sh
+{
+
+class TIntermNode;
+class TSymbolTable;
+
+void UnfoldShortCircuitToIf(TIntermNode *root, TSymbolTable *symbolTable);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_UNFOLDSHORTCIRCUIT_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/UseInterfaceBlockFields.cpp
@@ -0,0 +1,104 @@
+//
+// 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/UseInterfaceBlockFields.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 anonymous
+
+void UseInterfaceBlockFields(TIntermBlock *root,
+                             const InterfaceBlockList &blocks,
+                             const TSymbolTable &symbolTable)
+{
+    TIntermBlock *mainBody = FindMainBody(root);
+    InsertUseCode(mainBody->getSequence(), blocks, symbolTable);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/UseInterfaceBlockFields.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.
+//
+
+// 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_USEINTERFACEBLOCKFIELDS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_USEINTERFACEBLOCKFIELDS_H_
+
+#include <GLSLANG/ShaderLang.h>
+
+namespace sh
+{
+
+class TIntermBlock;
+class TSymbolTable;
+
+using InterfaceBlockList = std::vector<sh::InterfaceBlock>;
+
+void UseInterfaceBlockFields(TIntermBlock *root,
+                             const InterfaceBlockList &blocks,
+                             const TSymbolTable &symbolTable);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_USEINTERFACEBLOCKFIELDS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/VectorizeVectorScalarArithmetic.cpp
@@ -0,0 +1,288 @@
+// Copyright (c) 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.
+//
+// VectorizeVectorScalarArithmetic.cpp: Turn some arithmetic operations that operate on a float
+// vector-scalar pair into vector-vector operations. This is done recursively. Some scalar binary
+// operations inside vector constructors are also turned into vector operations.
+//
+// This is targeted to work around a bug in NVIDIA OpenGL drivers that was reproducible on NVIDIA
+// driver version 387.92. It works around the most common occurrences of the bug.
+
+#include "compiler/translator/tree_ops/VectorizeVectorScalarArithmetic.h"
+
+#include <set>
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class VectorizeVectorScalarArithmeticTraverser : public TIntermTraverser
+{
+  public:
+    VectorizeVectorScalarArithmeticTraverser(TSymbolTable *symbolTable)
+        : TIntermTraverser(true, false, false, symbolTable), mReplaced(false)
+    {
+    }
+
+    bool didReplaceScalarsWithVectors() { return mReplaced; }
+    void nextIteration()
+    {
+        mReplaced = false;
+        mModifiedBlocks.clear();
+    }
+
+  protected:
+    bool visitBinary(Visit visit, TIntermBinary *node) override;
+    bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+
+  private:
+    // These helpers should only be called from visitAggregate when visiting a constructor.
+    // argBinary is the only argument of the constructor.
+    void replaceMathInsideConstructor(TIntermAggregate *node, TIntermBinary *argBinary);
+    void replaceAssignInsideConstructor(const TIntermAggregate *node,
+                                        const TIntermBinary *argBinary);
+
+    static TIntermTyped *Vectorize(TIntermTyped *node,
+                                   TType vectorType,
+                                   TIntermTraverser::OriginalNode *originalNodeFate);
+
+    bool mReplaced;
+    std::set<const TIntermBlock *> mModifiedBlocks;
+};
+
+TIntermTyped *VectorizeVectorScalarArithmeticTraverser::Vectorize(
+    TIntermTyped *node,
+    TType vectorType,
+    TIntermTraverser::OriginalNode *originalNodeFate)
+{
+    ASSERT(node->isScalar());
+    vectorType.setQualifier(EvqTemporary);
+    TIntermSequence vectorConstructorArgs;
+    vectorConstructorArgs.push_back(node);
+    TIntermAggregate *vectorized =
+        TIntermAggregate::CreateConstructor(vectorType, &vectorConstructorArgs);
+    TIntermTyped *vectorizedFolded = vectorized->fold(nullptr);
+    if (originalNodeFate != nullptr)
+    {
+        if (vectorizedFolded != vectorized)
+        {
+            *originalNodeFate = OriginalNode::IS_DROPPED;
+        }
+        else
+        {
+            *originalNodeFate = OriginalNode::BECOMES_CHILD;
+        }
+    }
+    return vectorizedFolded;
+}
+
+bool VectorizeVectorScalarArithmeticTraverser::visitBinary(Visit /*visit*/, TIntermBinary *node)
+{
+    TIntermTyped *left  = node->getLeft();
+    TIntermTyped *right = node->getRight();
+    ASSERT(left);
+    ASSERT(right);
+    switch (node->getOp())
+    {
+        case EOpAdd:
+        case EOpAddAssign:
+            // Only these specific ops are necessary to turn into vector ops.
+            break;
+        default:
+            return true;
+    }
+    if (node->getBasicType() != EbtFloat)
+    {
+        // Only float ops have reproduced the bug.
+        return true;
+    }
+    if (left->isScalar() && right->isVector())
+    {
+        ASSERT(!node->isAssignment());
+        ASSERT(!right->isArray());
+        OriginalNode originalNodeFate;
+        TIntermTyped *leftVectorized = Vectorize(left, right->getType(), &originalNodeFate);
+        queueReplacementWithParent(node, left, leftVectorized, originalNodeFate);
+        mReplaced = true;
+        // Don't replace more nodes in the same subtree on this traversal. However, nodes elsewhere
+        // in the tree may still be replaced.
+        return false;
+    }
+    else if (left->isVector() && right->isScalar())
+    {
+        OriginalNode originalNodeFate;
+        TIntermTyped *rightVectorized = Vectorize(right, left->getType(), &originalNodeFate);
+        queueReplacementWithParent(node, right, rightVectorized, originalNodeFate);
+        mReplaced = true;
+        // Don't replace more nodes in the same subtree on this traversal. However, nodes elsewhere
+        // in the tree may still be replaced.
+        return false;
+    }
+    return true;
+}
+
+void VectorizeVectorScalarArithmeticTraverser::replaceMathInsideConstructor(
+    TIntermAggregate *node,
+    TIntermBinary *argBinary)
+{
+    // Turn:
+    //   a * b
+    // into:
+    //   gvec(a) * gvec(b)
+
+    TIntermTyped *left  = argBinary->getLeft();
+    TIntermTyped *right = argBinary->getRight();
+    ASSERT(left->isScalar() && right->isScalar());
+
+    TType leftVectorizedType = left->getType();
+    leftVectorizedType.setPrimarySize(static_cast<unsigned char>(node->getType().getNominalSize()));
+    TIntermTyped *leftVectorized = Vectorize(left, leftVectorizedType, nullptr);
+    TType rightVectorizedType    = right->getType();
+    rightVectorizedType.setPrimarySize(
+        static_cast<unsigned char>(node->getType().getNominalSize()));
+    TIntermTyped *rightVectorized = Vectorize(right, rightVectorizedType, nullptr);
+
+    TIntermBinary *newArg = new TIntermBinary(argBinary->getOp(), leftVectorized, rightVectorized);
+    queueReplacementWithParent(node, argBinary, newArg, OriginalNode::IS_DROPPED);
+}
+
+void VectorizeVectorScalarArithmeticTraverser::replaceAssignInsideConstructor(
+    const TIntermAggregate *node,
+    const TIntermBinary *argBinary)
+{
+    // Turn:
+    //   gvec(a *= b);
+    // into:
+    //   // This is inserted into the parent block:
+    //   gvec s0 = gvec(a);
+    //
+    //   // This goes where the gvec constructor used to be:
+    //   ((s0 *= b, a = s0.x), s0);
+
+    TIntermTyped *left  = argBinary->getLeft();
+    TIntermTyped *right = argBinary->getRight();
+    ASSERT(left->isScalar() && right->isScalar());
+    ASSERT(!left->hasSideEffects());
+
+    TType vecType = node->getType();
+    vecType.setQualifier(EvqTemporary);
+
+    // gvec s0 = gvec(a);
+    // s0 is called "tempAssignmentTarget" below.
+    TIntermTyped *tempAssignmentTargetInitializer = Vectorize(left->deepCopy(), vecType, nullptr);
+    TIntermDeclaration *tempAssignmentTargetDeclaration = nullptr;
+    TVariable *tempAssignmentTarget =
+        DeclareTempVariable(mSymbolTable, tempAssignmentTargetInitializer, EvqTemporary,
+                            &tempAssignmentTargetDeclaration);
+
+    // s0 *= b
+    TOperator compoundAssignmentOp = argBinary->getOp();
+    if (compoundAssignmentOp == EOpMulAssign)
+    {
+        compoundAssignmentOp = EOpVectorTimesScalarAssign;
+    }
+    TIntermBinary *replacementCompoundAssignment = new TIntermBinary(
+        compoundAssignmentOp, CreateTempSymbolNode(tempAssignmentTarget), right->deepCopy());
+
+    // s0.x
+    TVector<int> swizzleXOffset;
+    swizzleXOffset.push_back(0);
+    TIntermSwizzle *tempAssignmentTargetX =
+        new TIntermSwizzle(CreateTempSymbolNode(tempAssignmentTarget), swizzleXOffset);
+    // a = s0.x
+    TIntermBinary *replacementAssignBackToTarget =
+        new TIntermBinary(EOpAssign, left->deepCopy(), tempAssignmentTargetX);
+
+    // s0 *= b, a = s0.x
+    TIntermBinary *replacementSequenceLeft =
+        new TIntermBinary(EOpComma, replacementCompoundAssignment, replacementAssignBackToTarget);
+    // (s0 *= b, a = s0.x), s0
+    // Note that the created comma node is not const qualified in any case, so we can always pass
+    // shader version 300 here.
+    TIntermBinary *replacementSequence = TIntermBinary::CreateComma(
+        replacementSequenceLeft, CreateTempSymbolNode(tempAssignmentTarget), 300);
+
+    insertStatementInParentBlock(tempAssignmentTargetDeclaration);
+    queueReplacement(replacementSequence, OriginalNode::IS_DROPPED);
+}
+
+bool VectorizeVectorScalarArithmeticTraverser::visitAggregate(Visit /*visit*/,
+                                                              TIntermAggregate *node)
+{
+    // Transform scalar binary expressions inside vector constructors.
+    if (!node->isConstructor() || !node->isVector() || node->getSequence()->size() != 1)
+    {
+        return true;
+    }
+    TIntermTyped *argument = node->getSequence()->back()->getAsTyped();
+    ASSERT(argument);
+    if (!argument->isScalar() || argument->getBasicType() != EbtFloat)
+    {
+        return true;
+    }
+    TIntermBinary *argBinary = argument->getAsBinaryNode();
+    if (!argBinary)
+    {
+        return true;
+    }
+
+    // Only specific ops are necessary to change.
+    switch (argBinary->getOp())
+    {
+        case EOpMul:
+        case EOpDiv:
+        {
+            replaceMathInsideConstructor(node, argBinary);
+            mReplaced = true;
+            // Don't replace more nodes in the same subtree on this traversal. However, nodes
+            // elsewhere in the tree may still be replaced.
+            return false;
+        }
+        case EOpMulAssign:
+        case EOpDivAssign:
+        {
+            // The case where the left side has side effects is too complicated to deal with, so we
+            // leave that be.
+            if (!argBinary->getLeft()->hasSideEffects())
+            {
+                const TIntermBlock *parentBlock = getParentBlock();
+                // We can't do more than one insertion to the same block on the same traversal.
+                if (mModifiedBlocks.find(parentBlock) == mModifiedBlocks.end())
+                {
+                    replaceAssignInsideConstructor(node, argBinary);
+                    mModifiedBlocks.insert(parentBlock);
+                    mReplaced = true;
+                    // Don't replace more nodes in the same subtree on this traversal.
+                    // However, nodes elsewhere in the tree may still be replaced.
+                    return false;
+                }
+            }
+            break;
+        }
+        default:
+            return true;
+    }
+    return true;
+}
+
+}  // anonymous namespace
+
+void VectorizeVectorScalarArithmetic(TIntermBlock *root, TSymbolTable *symbolTable)
+{
+    VectorizeVectorScalarArithmeticTraverser traverser(symbolTable);
+    do
+    {
+        traverser.nextIteration();
+        root->traverse(&traverser);
+        traverser.updateTree();
+    } while (traverser.didReplaceScalarsWithVectors());
+}
+
+}  // namespace sh
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/VectorizeVectorScalarArithmetic.h
@@ -0,0 +1,25 @@
+// Copyright (c) 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.
+//
+// VectorizeVectorScalarArithmetic.h: Turn some arithmetic operations that operate on a float
+// vector-scalar pair into vector-vector operations. This is done recursively. Some scalar binary
+// operations inside vector constructors are also turned into vector operations.
+//
+// This is targeted to work around a bug in NVIDIA OpenGL drivers that was reproducible on NVIDIA
+// driver version 387.92. It works around the most common occurrences of the bug.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_VECTORIZEVECTORSCALARARITHMETIC_H_
+#define COMPILER_TRANSLATOR_TREEOPS_VECTORIZEVECTORSCALARARITHMETIC_H_
+
+namespace sh
+{
+
+class TIntermBlock;
+class TSymbolTable;
+
+void VectorizeVectorScalarArithmetic(TIntermBlock *root, TSymbolTable *symbolTable);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_VECTORIZEVECTORSCALARARITHMETIC_H_
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/WrapSwitchStatementsInBlocks.cpp
@@ -0,0 +1,126 @@
+//
+// Copyright (c) 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/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.push_back(NodeReplaceWithMultipleEntry(
+                node->getStatementList(), declaration, 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.
+void WrapSwitchStatementsInBlocks(TIntermBlock *root)
+{
+    WrapSwitchStatementsInBlocksTraverser traverser;
+    root->traverse(&traverser);
+    traverser.updateTree();
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/WrapSwitchStatementsInBlocks.h
@@ -0,0 +1,22 @@
+//
+// Copyright (c) 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_WRAPSWITCHSTATEMENTSINBLOCKS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_WRAPSWITCHSTATEMENTSINBLOCKS_H_
+
+namespace sh
+{
+
+class TIntermBlock;
+
+// Wrap switch statements in the AST into blocks when needed. Returns true if the AST was changed.
+void WrapSwitchStatementsInBlocks(TIntermBlock *root);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEOPS_WRAPSWITCHSTATEMENTSINBLOCKS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_autogen.h
@@ -0,0 +1,1334 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_builtin_symbols.py using data from builtin_variables.json and
+// builtin_function_declarations.txt.
+//
+// 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.
+//
+// BuiltIn_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 pt0B                             = TSymbolUniqueId(1);
+    static constexpr const TSymbolUniqueId radians_Float2                   = TSymbolUniqueId(2);
+    static constexpr const TSymbolUniqueId pt1B                             = TSymbolUniqueId(3);
+    static constexpr const TSymbolUniqueId radians_Float3                   = TSymbolUniqueId(4);
+    static constexpr const TSymbolUniqueId pt2B                             = TSymbolUniqueId(5);
+    static constexpr const TSymbolUniqueId radians_Float4                   = TSymbolUniqueId(6);
+    static constexpr const TSymbolUniqueId pt3B                             = 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 inversesqrt_Float1               = TSymbolUniqueId(88);
+    static constexpr const TSymbolUniqueId inversesqrt_Float2               = TSymbolUniqueId(89);
+    static constexpr const TSymbolUniqueId inversesqrt_Float3               = TSymbolUniqueId(90);
+    static constexpr const TSymbolUniqueId inversesqrt_Float4               = TSymbolUniqueId(91);
+    static constexpr const TSymbolUniqueId abs_Float1                       = TSymbolUniqueId(92);
+    static constexpr const TSymbolUniqueId abs_Float2                       = TSymbolUniqueId(93);
+    static constexpr const TSymbolUniqueId abs_Float3                       = TSymbolUniqueId(94);
+    static constexpr const TSymbolUniqueId abs_Float4                       = TSymbolUniqueId(95);
+    static constexpr const TSymbolUniqueId abs_Int1                         = TSymbolUniqueId(96);
+    static constexpr const TSymbolUniqueId pt0C                             = TSymbolUniqueId(97);
+    static constexpr const TSymbolUniqueId abs_Int2                         = TSymbolUniqueId(98);
+    static constexpr const TSymbolUniqueId pt1C                             = TSymbolUniqueId(99);
+    static constexpr const TSymbolUniqueId abs_Int3                         = TSymbolUniqueId(100);
+    static constexpr const TSymbolUniqueId pt2C                             = TSymbolUniqueId(101);
+    static constexpr const TSymbolUniqueId abs_Int4                         = TSymbolUniqueId(102);
+    static constexpr const TSymbolUniqueId pt3C                             = TSymbolUniqueId(103);
+    static constexpr const TSymbolUniqueId sign_Float1                      = TSymbolUniqueId(104);
+    static constexpr const TSymbolUniqueId sign_Float2                      = TSymbolUniqueId(105);
+    static constexpr const TSymbolUniqueId sign_Float3                      = TSymbolUniqueId(106);
+    static constexpr const TSymbolUniqueId sign_Float4                      = TSymbolUniqueId(107);
+    static constexpr const TSymbolUniqueId sign_Int1                        = TSymbolUniqueId(108);
+    static constexpr const TSymbolUniqueId sign_Int2                        = TSymbolUniqueId(109);
+    static constexpr const TSymbolUniqueId sign_Int3                        = TSymbolUniqueId(110);
+    static constexpr const TSymbolUniqueId sign_Int4                        = TSymbolUniqueId(111);
+    static constexpr const TSymbolUniqueId floor_Float1                     = TSymbolUniqueId(112);
+    static constexpr const TSymbolUniqueId floor_Float2                     = TSymbolUniqueId(113);
+    static constexpr const TSymbolUniqueId floor_Float3                     = TSymbolUniqueId(114);
+    static constexpr const TSymbolUniqueId floor_Float4                     = TSymbolUniqueId(115);
+    static constexpr const TSymbolUniqueId trunc_Float1                     = TSymbolUniqueId(116);
+    static constexpr const TSymbolUniqueId trunc_Float2                     = TSymbolUniqueId(117);
+    static constexpr const TSymbolUniqueId trunc_Float3                     = TSymbolUniqueId(118);
+    static constexpr const TSymbolUniqueId trunc_Float4                     = TSymbolUniqueId(119);
+    static constexpr const TSymbolUniqueId round_Float1                     = TSymbolUniqueId(120);
+    static constexpr const TSymbolUniqueId round_Float2                     = TSymbolUniqueId(121);
+    static constexpr const TSymbolUniqueId round_Float3                     = TSymbolUniqueId(122);
+    static constexpr const TSymbolUniqueId round_Float4                     = TSymbolUniqueId(123);
+    static constexpr const TSymbolUniqueId roundEven_Float1                 = TSymbolUniqueId(124);
+    static constexpr const TSymbolUniqueId roundEven_Float2                 = TSymbolUniqueId(125);
+    static constexpr const TSymbolUniqueId roundEven_Float3                 = TSymbolUniqueId(126);
+    static constexpr const TSymbolUniqueId roundEven_Float4                 = TSymbolUniqueId(127);
+    static constexpr const TSymbolUniqueId ceil_Float1                      = TSymbolUniqueId(128);
+    static constexpr const TSymbolUniqueId ceil_Float2                      = TSymbolUniqueId(129);
+    static constexpr const TSymbolUniqueId ceil_Float3                      = TSymbolUniqueId(130);
+    static constexpr const TSymbolUniqueId ceil_Float4                      = TSymbolUniqueId(131);
+    static constexpr const TSymbolUniqueId fract_Float1                     = TSymbolUniqueId(132);
+    static constexpr const TSymbolUniqueId fract_Float2                     = TSymbolUniqueId(133);
+    static constexpr const TSymbolUniqueId fract_Float3                     = TSymbolUniqueId(134);
+    static constexpr const TSymbolUniqueId fract_Float4                     = TSymbolUniqueId(135);
+    static constexpr const TSymbolUniqueId mod_Float1_Float1                = TSymbolUniqueId(136);
+    static constexpr const TSymbolUniqueId mod_Float2_Float1                = TSymbolUniqueId(137);
+    static constexpr const TSymbolUniqueId mod_Float3_Float1                = TSymbolUniqueId(138);
+    static constexpr const TSymbolUniqueId mod_Float4_Float1                = TSymbolUniqueId(139);
+    static constexpr const TSymbolUniqueId mod_Float2_Float2                = TSymbolUniqueId(140);
+    static constexpr const TSymbolUniqueId mod_Float3_Float3                = TSymbolUniqueId(141);
+    static constexpr const TSymbolUniqueId mod_Float4_Float4                = TSymbolUniqueId(142);
+    static constexpr const TSymbolUniqueId min_Float1_Float1                = TSymbolUniqueId(143);
+    static constexpr const TSymbolUniqueId min_Float2_Float1                = TSymbolUniqueId(144);
+    static constexpr const TSymbolUniqueId min_Float3_Float1                = TSymbolUniqueId(145);
+    static constexpr const TSymbolUniqueId min_Float4_Float1                = TSymbolUniqueId(146);
+    static constexpr const TSymbolUniqueId min_Float2_Float2                = TSymbolUniqueId(147);
+    static constexpr const TSymbolUniqueId min_Float3_Float3                = TSymbolUniqueId(148);
+    static constexpr const TSymbolUniqueId min_Float4_Float4                = TSymbolUniqueId(149);
+    static constexpr const TSymbolUniqueId min_Int1_Int1                    = TSymbolUniqueId(150);
+    static constexpr const TSymbolUniqueId min_Int2_Int2                    = TSymbolUniqueId(151);
+    static constexpr const TSymbolUniqueId min_Int3_Int3                    = TSymbolUniqueId(152);
+    static constexpr const TSymbolUniqueId min_Int4_Int4                    = TSymbolUniqueId(153);
+    static constexpr const TSymbolUniqueId min_Int2_Int1                    = TSymbolUniqueId(154);
+    static constexpr const TSymbolUniqueId min_Int3_Int1                    = TSymbolUniqueId(155);
+    static constexpr const TSymbolUniqueId min_Int4_Int1                    = TSymbolUniqueId(156);
+    static constexpr const TSymbolUniqueId min_UInt1_UInt1                  = TSymbolUniqueId(157);
+    static constexpr const TSymbolUniqueId pt0D                             = TSymbolUniqueId(158);
+    static constexpr const TSymbolUniqueId min_UInt2_UInt2                  = TSymbolUniqueId(159);
+    static constexpr const TSymbolUniqueId pt1D                             = TSymbolUniqueId(160);
+    static constexpr const TSymbolUniqueId min_UInt3_UInt3                  = TSymbolUniqueId(161);
+    static constexpr const TSymbolUniqueId pt2D                             = TSymbolUniqueId(162);
+    static constexpr const TSymbolUniqueId min_UInt4_UInt4                  = TSymbolUniqueId(163);
+    static constexpr const TSymbolUniqueId pt3D                             = TSymbolUniqueId(164);
+    static constexpr const TSymbolUniqueId min_UInt2_UInt1                  = TSymbolUniqueId(165);
+    static constexpr const TSymbolUniqueId min_UInt3_UInt1                  = TSymbolUniqueId(166);
+    static constexpr const TSymbolUniqueId min_UInt4_UInt1                  = TSymbolUniqueId(167);
+    static constexpr const TSymbolUniqueId max_Float1_Float1                = TSymbolUniqueId(168);
+    static constexpr const TSymbolUniqueId max_Float2_Float1                = TSymbolUniqueId(169);
+    static constexpr const TSymbolUniqueId max_Float3_Float1                = TSymbolUniqueId(170);
+    static constexpr const TSymbolUniqueId max_Float4_Float1                = TSymbolUniqueId(171);
+    static constexpr const TSymbolUniqueId max_Float2_Float2                = TSymbolUniqueId(172);
+    static constexpr const TSymbolUniqueId max_Float3_Float3                = TSymbolUniqueId(173);
+    static constexpr const TSymbolUniqueId max_Float4_Float4                = TSymbolUniqueId(174);
+    static constexpr const TSymbolUniqueId max_Int1_Int1                    = TSymbolUniqueId(175);
+    static constexpr const TSymbolUniqueId max_Int2_Int2                    = TSymbolUniqueId(176);
+    static constexpr const TSymbolUniqueId max_Int3_Int3                    = TSymbolUniqueId(177);
+    static constexpr const TSymbolUniqueId max_Int4_Int4                    = TSymbolUniqueId(178);
+    static constexpr const TSymbolUniqueId max_Int2_Int1                    = TSymbolUniqueId(179);
+    static constexpr const TSymbolUniqueId max_Int3_Int1                    = TSymbolUniqueId(180);
+    static constexpr const TSymbolUniqueId max_Int4_Int1                    = TSymbolUniqueId(181);
+    static constexpr const TSymbolUniqueId max_UInt1_UInt1                  = TSymbolUniqueId(182);
+    static constexpr const TSymbolUniqueId max_UInt2_UInt2                  = TSymbolUniqueId(183);
+    static constexpr const TSymbolUniqueId max_UInt3_UInt3                  = TSymbolUniqueId(184);
+    static constexpr const TSymbolUniqueId max_UInt4_UInt4                  = TSymbolUniqueId(185);
+    static constexpr const TSymbolUniqueId max_UInt2_UInt1                  = TSymbolUniqueId(186);
+    static constexpr const TSymbolUniqueId max_UInt3_UInt1                  = TSymbolUniqueId(187);
+    static constexpr const TSymbolUniqueId max_UInt4_UInt1                  = TSymbolUniqueId(188);
+    static constexpr const TSymbolUniqueId clamp_Float1_Float1_Float1       = TSymbolUniqueId(189);
+    static constexpr const TSymbolUniqueId clamp_Float2_Float1_Float1       = TSymbolUniqueId(190);
+    static constexpr const TSymbolUniqueId clamp_Float3_Float1_Float1       = TSymbolUniqueId(191);
+    static constexpr const TSymbolUniqueId clamp_Float4_Float1_Float1       = TSymbolUniqueId(192);
+    static constexpr const TSymbolUniqueId clamp_Float2_Float2_Float2       = TSymbolUniqueId(193);
+    static constexpr const TSymbolUniqueId clamp_Float3_Float3_Float3       = TSymbolUniqueId(194);
+    static constexpr const TSymbolUniqueId clamp_Float4_Float4_Float4       = TSymbolUniqueId(195);
+    static constexpr const TSymbolUniqueId clamp_Int1_Int1_Int1             = TSymbolUniqueId(196);
+    static constexpr const TSymbolUniqueId clamp_Int2_Int1_Int1             = TSymbolUniqueId(197);
+    static constexpr const TSymbolUniqueId clamp_Int3_Int1_Int1             = TSymbolUniqueId(198);
+    static constexpr const TSymbolUniqueId clamp_Int4_Int1_Int1             = TSymbolUniqueId(199);
+    static constexpr const TSymbolUniqueId clamp_Int2_Int2_Int2             = TSymbolUniqueId(200);
+    static constexpr const TSymbolUniqueId clamp_Int3_Int3_Int3             = TSymbolUniqueId(201);
+    static constexpr const TSymbolUniqueId clamp_Int4_Int4_Int4             = TSymbolUniqueId(202);
+    static constexpr const TSymbolUniqueId clamp_UInt1_UInt1_UInt1          = TSymbolUniqueId(203);
+    static constexpr const TSymbolUniqueId clamp_UInt2_UInt1_UInt1          = TSymbolUniqueId(204);
+    static constexpr const TSymbolUniqueId clamp_UInt3_UInt1_UInt1          = TSymbolUniqueId(205);
+    static constexpr const TSymbolUniqueId clamp_UInt4_UInt1_UInt1          = TSymbolUniqueId(206);
+    static constexpr const TSymbolUniqueId clamp_UInt2_UInt2_UInt2          = TSymbolUniqueId(207);
+    static constexpr const TSymbolUniqueId clamp_UInt3_UInt3_UInt3          = TSymbolUniqueId(208);
+    static constexpr const TSymbolUniqueId clamp_UInt4_UInt4_UInt4          = TSymbolUniqueId(209);
+    static constexpr const TSymbolUniqueId mix_Float1_Float1_Float1         = TSymbolUniqueId(210);
+    static constexpr const TSymbolUniqueId mix_Float2_Float2_Float1         = TSymbolUniqueId(211);
+    static constexpr const TSymbolUniqueId mix_Float3_Float3_Float1         = TSymbolUniqueId(212);
+    static constexpr const TSymbolUniqueId mix_Float4_Float4_Float1         = TSymbolUniqueId(213);
+    static constexpr const TSymbolUniqueId mix_Float2_Float2_Float2         = TSymbolUniqueId(214);
+    static constexpr const TSymbolUniqueId mix_Float3_Float3_Float3         = TSymbolUniqueId(215);
+    static constexpr const TSymbolUniqueId mix_Float4_Float4_Float4         = TSymbolUniqueId(216);
+    static constexpr const TSymbolUniqueId mix_Float1_Float1_Bool1          = TSymbolUniqueId(217);
+    static constexpr const TSymbolUniqueId pt0E                             = TSymbolUniqueId(218);
+    static constexpr const TSymbolUniqueId mix_Float2_Float2_Bool2          = TSymbolUniqueId(219);
+    static constexpr const TSymbolUniqueId pt1E                             = TSymbolUniqueId(220);
+    static constexpr const TSymbolUniqueId mix_Float3_Float3_Bool3          = TSymbolUniqueId(221);
+    static constexpr const TSymbolUniqueId pt2E                             = TSymbolUniqueId(222);
+    static constexpr const TSymbolUniqueId mix_Float4_Float4_Bool4          = TSymbolUniqueId(223);
+    static constexpr const TSymbolUniqueId pt3E                             = TSymbolUniqueId(224);
+    static constexpr const TSymbolUniqueId step_Float1_Float1               = TSymbolUniqueId(225);
+    static constexpr const TSymbolUniqueId step_Float2_Float2               = TSymbolUniqueId(226);
+    static constexpr const TSymbolUniqueId step_Float3_Float3               = TSymbolUniqueId(227);
+    static constexpr const TSymbolUniqueId step_Float4_Float4               = TSymbolUniqueId(228);
+    static constexpr const TSymbolUniqueId step_Float1_Float2               = TSymbolUniqueId(229);
+    static constexpr const TSymbolUniqueId step_Float1_Float3               = TSymbolUniqueId(230);
+    static constexpr const TSymbolUniqueId step_Float1_Float4               = TSymbolUniqueId(231);
+    static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float1  = TSymbolUniqueId(232);
+    static constexpr const TSymbolUniqueId smoothstep_Float2_Float2_Float2  = TSymbolUniqueId(233);
+    static constexpr const TSymbolUniqueId smoothstep_Float3_Float3_Float3  = TSymbolUniqueId(234);
+    static constexpr const TSymbolUniqueId smoothstep_Float4_Float4_Float4  = TSymbolUniqueId(235);
+    static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float2  = TSymbolUniqueId(236);
+    static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float3  = TSymbolUniqueId(237);
+    static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float4  = TSymbolUniqueId(238);
+    static constexpr const TSymbolUniqueId modf_Float1_Float1               = TSymbolUniqueId(239);
+    static constexpr const TSymbolUniqueId pt_o_0B                          = TSymbolUniqueId(240);
+    static constexpr const TSymbolUniqueId modf_Float2_Float2               = TSymbolUniqueId(241);
+    static constexpr const TSymbolUniqueId pt_o_1B                          = TSymbolUniqueId(242);
+    static constexpr const TSymbolUniqueId modf_Float3_Float3               = TSymbolUniqueId(243);
+    static constexpr const TSymbolUniqueId pt_o_2B                          = TSymbolUniqueId(244);
+    static constexpr const TSymbolUniqueId modf_Float4_Float4               = TSymbolUniqueId(245);
+    static constexpr const TSymbolUniqueId pt_o_3B                          = TSymbolUniqueId(246);
+    static constexpr const TSymbolUniqueId isnan_Float1                     = TSymbolUniqueId(247);
+    static constexpr const TSymbolUniqueId isnan_Float2                     = TSymbolUniqueId(248);
+    static constexpr const TSymbolUniqueId isnan_Float3                     = TSymbolUniqueId(249);
+    static constexpr const TSymbolUniqueId isnan_Float4                     = TSymbolUniqueId(250);
+    static constexpr const TSymbolUniqueId isinf_Float1                     = TSymbolUniqueId(251);
+    static constexpr const TSymbolUniqueId isinf_Float2                     = TSymbolUniqueId(252);
+    static constexpr const TSymbolUniqueId isinf_Float3                     = TSymbolUniqueId(253);
+    static constexpr const TSymbolUniqueId isinf_Float4                     = TSymbolUniqueId(254);
+    static constexpr const TSymbolUniqueId floatBitsToInt_Float1            = TSymbolUniqueId(255);
+    static constexpr const TSymbolUniqueId floatBitsToInt_Float2            = TSymbolUniqueId(256);
+    static constexpr const TSymbolUniqueId floatBitsToInt_Float3            = TSymbolUniqueId(257);
+    static constexpr const TSymbolUniqueId floatBitsToInt_Float4            = TSymbolUniqueId(258);
+    static constexpr const TSymbolUniqueId floatBitsToUint_Float1           = TSymbolUniqueId(259);
+    static constexpr const TSymbolUniqueId floatBitsToUint_Float2           = TSymbolUniqueId(260);
+    static constexpr const TSymbolUniqueId floatBitsToUint_Float3           = TSymbolUniqueId(261);
+    static constexpr const TSymbolUniqueId floatBitsToUint_Float4           = TSymbolUniqueId(262);
+    static constexpr const TSymbolUniqueId intBitsToFloat_Int1              = TSymbolUniqueId(263);
+    static constexpr const TSymbolUniqueId intBitsToFloat_Int2              = TSymbolUniqueId(264);
+    static constexpr const TSymbolUniqueId intBitsToFloat_Int3              = TSymbolUniqueId(265);
+    static constexpr const TSymbolUniqueId intBitsToFloat_Int4              = TSymbolUniqueId(266);
+    static constexpr const TSymbolUniqueId uintBitsToFloat_UInt1            = TSymbolUniqueId(267);
+    static constexpr const TSymbolUniqueId uintBitsToFloat_UInt2            = TSymbolUniqueId(268);
+    static constexpr const TSymbolUniqueId uintBitsToFloat_UInt3            = TSymbolUniqueId(269);
+    static constexpr const TSymbolUniqueId uintBitsToFloat_UInt4            = TSymbolUniqueId(270);
+    static constexpr const TSymbolUniqueId frexp_Float1_Int1                = TSymbolUniqueId(271);
+    static constexpr const TSymbolUniqueId pt_o_0C                          = TSymbolUniqueId(272);
+    static constexpr const TSymbolUniqueId frexp_Float2_Int2                = TSymbolUniqueId(273);
+    static constexpr const TSymbolUniqueId pt_o_1C                          = TSymbolUniqueId(274);
+    static constexpr const TSymbolUniqueId frexp_Float3_Int3                = TSymbolUniqueId(275);
+    static constexpr const TSymbolUniqueId pt_o_2C                          = TSymbolUniqueId(276);
+    static constexpr const TSymbolUniqueId frexp_Float4_Int4                = TSymbolUniqueId(277);
+    static constexpr const TSymbolUniqueId pt_o_3C                          = TSymbolUniqueId(278);
+    static constexpr const TSymbolUniqueId ldexp_Float1_Int1                = TSymbolUniqueId(279);
+    static constexpr const TSymbolUniqueId ldexp_Float2_Int2                = TSymbolUniqueId(280);
+    static constexpr const TSymbolUniqueId ldexp_Float3_Int3                = TSymbolUniqueId(281);
+    static constexpr const TSymbolUniqueId ldexp_Float4_Int4                = TSymbolUniqueId(282);
+    static constexpr const TSymbolUniqueId packSnorm2x16_Float2             = TSymbolUniqueId(283);
+    static constexpr const TSymbolUniqueId packUnorm2x16_Float2             = TSymbolUniqueId(284);
+    static constexpr const TSymbolUniqueId packHalf2x16_Float2              = TSymbolUniqueId(285);
+    static constexpr const TSymbolUniqueId unpackSnorm2x16_UInt1            = TSymbolUniqueId(286);
+    static constexpr const TSymbolUniqueId unpackUnorm2x16_UInt1            = TSymbolUniqueId(287);
+    static constexpr const TSymbolUniqueId unpackHalf2x16_UInt1             = TSymbolUniqueId(288);
+    static constexpr const TSymbolUniqueId packUnorm4x8_Float4              = TSymbolUniqueId(289);
+    static constexpr const TSymbolUniqueId packSnorm4x8_Float4              = TSymbolUniqueId(290);
+    static constexpr const TSymbolUniqueId unpackUnorm4x8_UInt1             = TSymbolUniqueId(291);
+    static constexpr const TSymbolUniqueId unpackSnorm4x8_UInt1             = TSymbolUniqueId(292);
+    static constexpr const TSymbolUniqueId length_Float1                    = TSymbolUniqueId(293);
+    static constexpr const TSymbolUniqueId length_Float2                    = TSymbolUniqueId(294);
+    static constexpr const TSymbolUniqueId length_Float3                    = TSymbolUniqueId(295);
+    static constexpr const TSymbolUniqueId length_Float4                    = TSymbolUniqueId(296);
+    static constexpr const TSymbolUniqueId distance_Float1_Float1           = TSymbolUniqueId(297);
+    static constexpr const TSymbolUniqueId distance_Float2_Float2           = TSymbolUniqueId(298);
+    static constexpr const TSymbolUniqueId distance_Float3_Float3           = TSymbolUniqueId(299);
+    static constexpr const TSymbolUniqueId distance_Float4_Float4           = TSymbolUniqueId(300);
+    static constexpr const TSymbolUniqueId dot_Float1_Float1                = TSymbolUniqueId(301);
+    static constexpr const TSymbolUniqueId dot_Float2_Float2                = TSymbolUniqueId(302);
+    static constexpr const TSymbolUniqueId dot_Float3_Float3                = TSymbolUniqueId(303);
+    static constexpr const TSymbolUniqueId dot_Float4_Float4                = TSymbolUniqueId(304);
+    static constexpr const TSymbolUniqueId cross_Float3_Float3              = TSymbolUniqueId(305);
+    static constexpr const TSymbolUniqueId normalize_Float1                 = TSymbolUniqueId(306);
+    static constexpr const TSymbolUniqueId normalize_Float2                 = TSymbolUniqueId(307);
+    static constexpr const TSymbolUniqueId normalize_Float3                 = TSymbolUniqueId(308);
+    static constexpr const TSymbolUniqueId normalize_Float4                 = TSymbolUniqueId(309);
+    static constexpr const TSymbolUniqueId faceforward_Float1_Float1_Float1 = TSymbolUniqueId(310);
+    static constexpr const TSymbolUniqueId faceforward_Float2_Float2_Float2 = TSymbolUniqueId(311);
+    static constexpr const TSymbolUniqueId faceforward_Float3_Float3_Float3 = TSymbolUniqueId(312);
+    static constexpr const TSymbolUniqueId faceforward_Float4_Float4_Float4 = TSymbolUniqueId(313);
+    static constexpr const TSymbolUniqueId reflect_Float1_Float1            = TSymbolUniqueId(314);
+    static constexpr const TSymbolUniqueId reflect_Float2_Float2            = TSymbolUniqueId(315);
+    static constexpr const TSymbolUniqueId reflect_Float3_Float3            = TSymbolUniqueId(316);
+    static constexpr const TSymbolUniqueId reflect_Float4_Float4            = TSymbolUniqueId(317);
+    static constexpr const TSymbolUniqueId refract_Float1_Float1_Float1     = TSymbolUniqueId(318);
+    static constexpr const TSymbolUniqueId refract_Float2_Float2_Float1     = TSymbolUniqueId(319);
+    static constexpr const TSymbolUniqueId refract_Float3_Float3_Float1     = TSymbolUniqueId(320);
+    static constexpr const TSymbolUniqueId refract_Float4_Float4_Float1     = TSymbolUniqueId(321);
+    static constexpr const TSymbolUniqueId matrixCompMult_Float2x2_Float2x2 = TSymbolUniqueId(322);
+    static constexpr const TSymbolUniqueId pt5B                             = TSymbolUniqueId(323);
+    static constexpr const TSymbolUniqueId matrixCompMult_Float3x3_Float3x3 = TSymbolUniqueId(324);
+    static constexpr const TSymbolUniqueId ptAB                             = TSymbolUniqueId(325);
+    static constexpr const TSymbolUniqueId matrixCompMult_Float4x4_Float4x4 = TSymbolUniqueId(326);
+    static constexpr const TSymbolUniqueId ptFB                             = TSymbolUniqueId(327);
+    static constexpr const TSymbolUniqueId matrixCompMult_Float2x3_Float2x3 = TSymbolUniqueId(328);
+    static constexpr const TSymbolUniqueId pt9B                             = TSymbolUniqueId(329);
+    static constexpr const TSymbolUniqueId matrixCompMult_Float3x2_Float3x2 = TSymbolUniqueId(330);
+    static constexpr const TSymbolUniqueId pt6B                             = TSymbolUniqueId(331);
+    static constexpr const TSymbolUniqueId matrixCompMult_Float2x4_Float2x4 = TSymbolUniqueId(332);
+    static constexpr const TSymbolUniqueId ptDB                             = TSymbolUniqueId(333);
+    static constexpr const TSymbolUniqueId matrixCompMult_Float4x2_Float4x2 = TSymbolUniqueId(334);
+    static constexpr const TSymbolUniqueId pt7B                             = TSymbolUniqueId(335);
+    static constexpr const TSymbolUniqueId matrixCompMult_Float3x4_Float3x4 = TSymbolUniqueId(336);
+    static constexpr const TSymbolUniqueId ptEB                             = TSymbolUniqueId(337);
+    static constexpr const TSymbolUniqueId matrixCompMult_Float4x3_Float4x3 = TSymbolUniqueId(338);
+    static constexpr const TSymbolUniqueId ptBB                             = TSymbolUniqueId(339);
+    static constexpr const TSymbolUniqueId outerProduct_Float2_Float2       = TSymbolUniqueId(340);
+    static constexpr const TSymbolUniqueId outerProduct_Float3_Float3       = TSymbolUniqueId(341);
+    static constexpr const TSymbolUniqueId outerProduct_Float4_Float4       = TSymbolUniqueId(342);
+    static constexpr const TSymbolUniqueId outerProduct_Float3_Float2       = TSymbolUniqueId(343);
+    static constexpr const TSymbolUniqueId outerProduct_Float2_Float3       = TSymbolUniqueId(344);
+    static constexpr const TSymbolUniqueId outerProduct_Float4_Float2       = TSymbolUniqueId(345);
+    static constexpr const TSymbolUniqueId outerProduct_Float2_Float4       = TSymbolUniqueId(346);
+    static constexpr const TSymbolUniqueId outerProduct_Float4_Float3       = TSymbolUniqueId(347);
+    static constexpr const TSymbolUniqueId outerProduct_Float3_Float4       = TSymbolUniqueId(348);
+    static constexpr const TSymbolUniqueId transpose_Float2x2               = TSymbolUniqueId(349);
+    static constexpr const TSymbolUniqueId transpose_Float3x3               = TSymbolUniqueId(350);
+    static constexpr const TSymbolUniqueId transpose_Float4x4               = TSymbolUniqueId(351);
+    static constexpr const TSymbolUniqueId transpose_Float3x2               = TSymbolUniqueId(352);
+    static constexpr const TSymbolUniqueId transpose_Float2x3               = TSymbolUniqueId(353);
+    static constexpr const TSymbolUniqueId transpose_Float4x2               = TSymbolUniqueId(354);
+    static constexpr const TSymbolUniqueId transpose_Float2x4               = TSymbolUniqueId(355);
+    static constexpr const TSymbolUniqueId transpose_Float4x3               = TSymbolUniqueId(356);
+    static constexpr const TSymbolUniqueId transpose_Float3x4               = TSymbolUniqueId(357);
+    static constexpr const TSymbolUniqueId determinant_Float2x2             = TSymbolUniqueId(358);
+    static constexpr const TSymbolUniqueId determinant_Float3x3             = TSymbolUniqueId(359);
+    static constexpr const TSymbolUniqueId determinant_Float4x4             = TSymbolUniqueId(360);
+    static constexpr const TSymbolUniqueId inverse_Float2x2                 = TSymbolUniqueId(361);
+    static constexpr const TSymbolUniqueId inverse_Float3x3                 = TSymbolUniqueId(362);
+    static constexpr const TSymbolUniqueId inverse_Float4x4                 = TSymbolUniqueId(363);
+    static constexpr const TSymbolUniqueId lessThan_Float2_Float2           = TSymbolUniqueId(364);
+    static constexpr const TSymbolUniqueId lessThan_Float3_Float3           = TSymbolUniqueId(365);
+    static constexpr const TSymbolUniqueId lessThan_Float4_Float4           = TSymbolUniqueId(366);
+    static constexpr const TSymbolUniqueId lessThan_Int2_Int2               = TSymbolUniqueId(367);
+    static constexpr const TSymbolUniqueId lessThan_Int3_Int3               = TSymbolUniqueId(368);
+    static constexpr const TSymbolUniqueId lessThan_Int4_Int4               = TSymbolUniqueId(369);
+    static constexpr const TSymbolUniqueId lessThan_UInt2_UInt2             = TSymbolUniqueId(370);
+    static constexpr const TSymbolUniqueId lessThan_UInt3_UInt3             = TSymbolUniqueId(371);
+    static constexpr const TSymbolUniqueId lessThan_UInt4_UInt4             = TSymbolUniqueId(372);
+    static constexpr const TSymbolUniqueId lessThanEqual_Float2_Float2      = TSymbolUniqueId(373);
+    static constexpr const TSymbolUniqueId lessThanEqual_Float3_Float3      = TSymbolUniqueId(374);
+    static constexpr const TSymbolUniqueId lessThanEqual_Float4_Float4      = TSymbolUniqueId(375);
+    static constexpr const TSymbolUniqueId lessThanEqual_Int2_Int2          = TSymbolUniqueId(376);
+    static constexpr const TSymbolUniqueId lessThanEqual_Int3_Int3          = TSymbolUniqueId(377);
+    static constexpr const TSymbolUniqueId lessThanEqual_Int4_Int4          = TSymbolUniqueId(378);
+    static constexpr const TSymbolUniqueId lessThanEqual_UInt2_UInt2        = TSymbolUniqueId(379);
+    static constexpr const TSymbolUniqueId lessThanEqual_UInt3_UInt3        = TSymbolUniqueId(380);
+    static constexpr const TSymbolUniqueId lessThanEqual_UInt4_UInt4        = TSymbolUniqueId(381);
+    static constexpr const TSymbolUniqueId greaterThan_Float2_Float2        = TSymbolUniqueId(382);
+    static constexpr const TSymbolUniqueId greaterThan_Float3_Float3        = TSymbolUniqueId(383);
+    static constexpr const TSymbolUniqueId greaterThan_Float4_Float4        = TSymbolUniqueId(384);
+    static constexpr const TSymbolUniqueId greaterThan_Int2_Int2            = TSymbolUniqueId(385);
+    static constexpr const TSymbolUniqueId greaterThan_Int3_Int3            = TSymbolUniqueId(386);
+    static constexpr const TSymbolUniqueId greaterThan_Int4_Int4            = TSymbolUniqueId(387);
+    static constexpr const TSymbolUniqueId greaterThan_UInt2_UInt2          = TSymbolUniqueId(388);
+    static constexpr const TSymbolUniqueId greaterThan_UInt3_UInt3          = TSymbolUniqueId(389);
+    static constexpr const TSymbolUniqueId greaterThan_UInt4_UInt4          = TSymbolUniqueId(390);
+    static constexpr const TSymbolUniqueId greaterThanEqual_Float2_Float2   = TSymbolUniqueId(391);
+    static constexpr const TSymbolUniqueId greaterThanEqual_Float3_Float3   = TSymbolUniqueId(392);
+    static constexpr const TSymbolUniqueId greaterThanEqual_Float4_Float4   = TSymbolUniqueId(393);
+    static constexpr const TSymbolUniqueId greaterThanEqual_Int2_Int2       = TSymbolUniqueId(394);
+    static constexpr const TSymbolUniqueId greaterThanEqual_Int3_Int3       = TSymbolUniqueId(395);
+    static constexpr const TSymbolUniqueId greaterThanEqual_Int4_Int4       = TSymbolUniqueId(396);
+    static constexpr const TSymbolUniqueId greaterThanEqual_UInt2_UInt2     = TSymbolUniqueId(397);
+    static constexpr const TSymbolUniqueId greaterThanEqual_UInt3_UInt3     = TSymbolUniqueId(398);
+    static constexpr const TSymbolUniqueId greaterThanEqual_UInt4_UInt4     = TSymbolUniqueId(399);
+    static constexpr const TSymbolUniqueId equal_Float2_Float2              = TSymbolUniqueId(400);
+    static constexpr const TSymbolUniqueId equal_Float3_Float3              = TSymbolUniqueId(401);
+    static constexpr const TSymbolUniqueId equal_Float4_Float4              = TSymbolUniqueId(402);
+    static constexpr const TSymbolUniqueId equal_Int2_Int2                  = TSymbolUniqueId(403);
+    static constexpr const TSymbolUniqueId equal_Int3_Int3                  = TSymbolUniqueId(404);
+    static constexpr const TSymbolUniqueId equal_Int4_Int4                  = TSymbolUniqueId(405);
+    static constexpr const TSymbolUniqueId equal_UInt2_UInt2                = TSymbolUniqueId(406);
+    static constexpr const TSymbolUniqueId equal_UInt3_UInt3                = TSymbolUniqueId(407);
+    static constexpr const TSymbolUniqueId equal_UInt4_UInt4                = TSymbolUniqueId(408);
+    static constexpr const TSymbolUniqueId equal_Bool2_Bool2                = TSymbolUniqueId(409);
+    static constexpr const TSymbolUniqueId equal_Bool3_Bool3                = TSymbolUniqueId(410);
+    static constexpr const TSymbolUniqueId equal_Bool4_Bool4                = TSymbolUniqueId(411);
+    static constexpr const TSymbolUniqueId notEqual_Float2_Float2           = TSymbolUniqueId(412);
+    static constexpr const TSymbolUniqueId notEqual_Float3_Float3           = TSymbolUniqueId(413);
+    static constexpr const TSymbolUniqueId notEqual_Float4_Float4           = TSymbolUniqueId(414);
+    static constexpr const TSymbolUniqueId notEqual_Int2_Int2               = TSymbolUniqueId(415);
+    static constexpr const TSymbolUniqueId notEqual_Int3_Int3               = TSymbolUniqueId(416);
+    static constexpr const TSymbolUniqueId notEqual_Int4_Int4               = TSymbolUniqueId(417);
+    static constexpr const TSymbolUniqueId notEqual_UInt2_UInt2             = TSymbolUniqueId(418);
+    static constexpr const TSymbolUniqueId notEqual_UInt3_UInt3             = TSymbolUniqueId(419);
+    static constexpr const TSymbolUniqueId notEqual_UInt4_UInt4             = TSymbolUniqueId(420);
+    static constexpr const TSymbolUniqueId notEqual_Bool2_Bool2             = TSymbolUniqueId(421);
+    static constexpr const TSymbolUniqueId notEqual_Bool3_Bool3             = TSymbolUniqueId(422);
+    static constexpr const TSymbolUniqueId notEqual_Bool4_Bool4             = TSymbolUniqueId(423);
+    static constexpr const TSymbolUniqueId any_Bool2                        = TSymbolUniqueId(424);
+    static constexpr const TSymbolUniqueId any_Bool3                        = TSymbolUniqueId(425);
+    static constexpr const TSymbolUniqueId any_Bool4                        = TSymbolUniqueId(426);
+    static constexpr const TSymbolUniqueId all_Bool2                        = TSymbolUniqueId(427);
+    static constexpr const TSymbolUniqueId all_Bool3                        = TSymbolUniqueId(428);
+    static constexpr const TSymbolUniqueId all_Bool4                        = TSymbolUniqueId(429);
+    static constexpr const TSymbolUniqueId notFunc_Bool2                    = TSymbolUniqueId(430);
+    static constexpr const TSymbolUniqueId notFunc_Bool3                    = TSymbolUniqueId(431);
+    static constexpr const TSymbolUniqueId notFunc_Bool4                    = TSymbolUniqueId(432);
+    static constexpr const TSymbolUniqueId bitfieldExtract_Int1_Int1_Int1   = TSymbolUniqueId(433);
+    static constexpr const TSymbolUniqueId bitfieldExtract_Int2_Int1_Int1   = TSymbolUniqueId(434);
+    static constexpr const TSymbolUniqueId bitfieldExtract_Int3_Int1_Int1   = TSymbolUniqueId(435);
+    static constexpr const TSymbolUniqueId bitfieldExtract_Int4_Int1_Int1   = TSymbolUniqueId(436);
+    static constexpr const TSymbolUniqueId bitfieldExtract_UInt1_Int1_Int1  = TSymbolUniqueId(437);
+    static constexpr const TSymbolUniqueId bitfieldExtract_UInt2_Int1_Int1  = TSymbolUniqueId(438);
+    static constexpr const TSymbolUniqueId bitfieldExtract_UInt3_Int1_Int1  = TSymbolUniqueId(439);
+    static constexpr const TSymbolUniqueId bitfieldExtract_UInt4_Int1_Int1  = TSymbolUniqueId(440);
+    static constexpr const TSymbolUniqueId bitfieldInsert_Int1_Int1_Int1_Int1 =
+        TSymbolUniqueId(441);
+    static constexpr const TSymbolUniqueId bitfieldInsert_Int2_Int2_Int1_Int1 =
+        TSymbolUniqueId(442);
+    static constexpr const TSymbolUniqueId bitfieldInsert_Int3_Int3_Int1_Int1 =
+        TSymbolUniqueId(443);
+    static constexpr const TSymbolUniqueId bitfieldInsert_Int4_Int4_Int1_Int1 =
+        TSymbolUniqueId(444);
+    static constexpr const TSymbolUniqueId bitfieldInsert_UInt1_UInt1_Int1_Int1 =
+        TSymbolUniqueId(445);
+    static constexpr const TSymbolUniqueId bitfieldInsert_UInt2_UInt2_Int1_Int1 =
+        TSymbolUniqueId(446);
+    static constexpr const TSymbolUniqueId bitfieldInsert_UInt3_UInt3_Int1_Int1 =
+        TSymbolUniqueId(447);
+    static constexpr const TSymbolUniqueId bitfieldInsert_UInt4_UInt4_Int1_Int1 =
+        TSymbolUniqueId(448);
+    static constexpr const TSymbolUniqueId bitfieldReverse_Int1         = TSymbolUniqueId(449);
+    static constexpr const TSymbolUniqueId bitfieldReverse_Int2         = TSymbolUniqueId(450);
+    static constexpr const TSymbolUniqueId bitfieldReverse_Int3         = TSymbolUniqueId(451);
+    static constexpr const TSymbolUniqueId bitfieldReverse_Int4         = TSymbolUniqueId(452);
+    static constexpr const TSymbolUniqueId bitfieldReverse_UInt1        = TSymbolUniqueId(453);
+    static constexpr const TSymbolUniqueId bitfieldReverse_UInt2        = TSymbolUniqueId(454);
+    static constexpr const TSymbolUniqueId bitfieldReverse_UInt3        = TSymbolUniqueId(455);
+    static constexpr const TSymbolUniqueId bitfieldReverse_UInt4        = TSymbolUniqueId(456);
+    static constexpr const TSymbolUniqueId bitCount_Int1                = TSymbolUniqueId(457);
+    static constexpr const TSymbolUniqueId bitCount_Int2                = TSymbolUniqueId(458);
+    static constexpr const TSymbolUniqueId bitCount_Int3                = TSymbolUniqueId(459);
+    static constexpr const TSymbolUniqueId bitCount_Int4                = TSymbolUniqueId(460);
+    static constexpr const TSymbolUniqueId bitCount_UInt1               = TSymbolUniqueId(461);
+    static constexpr const TSymbolUniqueId bitCount_UInt2               = TSymbolUniqueId(462);
+    static constexpr const TSymbolUniqueId bitCount_UInt3               = TSymbolUniqueId(463);
+    static constexpr const TSymbolUniqueId bitCount_UInt4               = TSymbolUniqueId(464);
+    static constexpr const TSymbolUniqueId findLSB_Int1                 = TSymbolUniqueId(465);
+    static constexpr const TSymbolUniqueId findLSB_Int2                 = TSymbolUniqueId(466);
+    static constexpr const TSymbolUniqueId findLSB_Int3                 = TSymbolUniqueId(467);
+    static constexpr const TSymbolUniqueId findLSB_Int4                 = TSymbolUniqueId(468);
+    static constexpr const TSymbolUniqueId findLSB_UInt1                = TSymbolUniqueId(469);
+    static constexpr const TSymbolUniqueId findLSB_UInt2                = TSymbolUniqueId(470);
+    static constexpr const TSymbolUniqueId findLSB_UInt3                = TSymbolUniqueId(471);
+    static constexpr const TSymbolUniqueId findLSB_UInt4                = TSymbolUniqueId(472);
+    static constexpr const TSymbolUniqueId findMSB_Int1                 = TSymbolUniqueId(473);
+    static constexpr const TSymbolUniqueId findMSB_Int2                 = TSymbolUniqueId(474);
+    static constexpr const TSymbolUniqueId findMSB_Int3                 = TSymbolUniqueId(475);
+    static constexpr const TSymbolUniqueId findMSB_Int4                 = TSymbolUniqueId(476);
+    static constexpr const TSymbolUniqueId findMSB_UInt1                = TSymbolUniqueId(477);
+    static constexpr const TSymbolUniqueId findMSB_UInt2                = TSymbolUniqueId(478);
+    static constexpr const TSymbolUniqueId findMSB_UInt3                = TSymbolUniqueId(479);
+    static constexpr const TSymbolUniqueId findMSB_UInt4                = TSymbolUniqueId(480);
+    static constexpr const TSymbolUniqueId uaddCarry_UInt1_UInt1_UInt1  = TSymbolUniqueId(481);
+    static constexpr const TSymbolUniqueId pt_o_0D                      = TSymbolUniqueId(482);
+    static constexpr const TSymbolUniqueId uaddCarry_UInt2_UInt2_UInt2  = TSymbolUniqueId(483);
+    static constexpr const TSymbolUniqueId pt_o_1D                      = TSymbolUniqueId(484);
+    static constexpr const TSymbolUniqueId uaddCarry_UInt3_UInt3_UInt3  = TSymbolUniqueId(485);
+    static constexpr const TSymbolUniqueId pt_o_2D                      = TSymbolUniqueId(486);
+    static constexpr const TSymbolUniqueId uaddCarry_UInt4_UInt4_UInt4  = TSymbolUniqueId(487);
+    static constexpr const TSymbolUniqueId pt_o_3D                      = TSymbolUniqueId(488);
+    static constexpr const TSymbolUniqueId usubBorrow_UInt1_UInt1_UInt1 = TSymbolUniqueId(489);
+    static constexpr const TSymbolUniqueId usubBorrow_UInt2_UInt2_UInt2 = TSymbolUniqueId(490);
+    static constexpr const TSymbolUniqueId usubBorrow_UInt3_UInt3_UInt3 = TSymbolUniqueId(491);
+    static constexpr const TSymbolUniqueId usubBorrow_UInt4_UInt4_UInt4 = TSymbolUniqueId(492);
+    static constexpr const TSymbolUniqueId umulExtended_UInt1_UInt1_UInt1_UInt1 =
+        TSymbolUniqueId(493);
+    static constexpr const TSymbolUniqueId umulExtended_UInt2_UInt2_UInt2_UInt2 =
+        TSymbolUniqueId(494);
+    static constexpr const TSymbolUniqueId umulExtended_UInt3_UInt3_UInt3_UInt3 =
+        TSymbolUniqueId(495);
+    static constexpr const TSymbolUniqueId umulExtended_UInt4_UInt4_UInt4_UInt4 =
+        TSymbolUniqueId(496);
+    static constexpr const TSymbolUniqueId imulExtended_Int1_Int1_Int1_Int1 = TSymbolUniqueId(497);
+    static constexpr const TSymbolUniqueId imulExtended_Int2_Int2_Int2_Int2 = TSymbolUniqueId(498);
+    static constexpr const TSymbolUniqueId imulExtended_Int3_Int3_Int3_Int3 = TSymbolUniqueId(499);
+    static constexpr const TSymbolUniqueId imulExtended_Int4_Int4_Int4_Int4 = TSymbolUniqueId(500);
+    static constexpr const TSymbolUniqueId texture2D_Sampler2D1_Float2      = TSymbolUniqueId(501);
+    static constexpr const TSymbolUniqueId pt0H                             = TSymbolUniqueId(502);
+    static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float3  = TSymbolUniqueId(503);
+    static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float4  = TSymbolUniqueId(504);
+    static constexpr const TSymbolUniqueId textureCube_SamplerCube1_Float3  = TSymbolUniqueId(505);
+    static constexpr const TSymbolUniqueId pt0J                             = TSymbolUniqueId(506);
+    static constexpr const TSymbolUniqueId texture2D_SamplerExternalOES1_Float2 =
+        TSymbolUniqueId(507);
+    static constexpr const TSymbolUniqueId pt0L = TSymbolUniqueId(508);
+    static constexpr const TSymbolUniqueId texture2DProj_SamplerExternalOES1_Float3 =
+        TSymbolUniqueId(509);
+    static constexpr const TSymbolUniqueId texture2DProj_SamplerExternalOES1_Float4 =
+        TSymbolUniqueId(510);
+    static constexpr const TSymbolUniqueId texture2DRect_Sampler2DRect1_Float2 =
+        TSymbolUniqueId(511);
+    static constexpr const TSymbolUniqueId pt0N = TSymbolUniqueId(512);
+    static constexpr const TSymbolUniqueId texture2DRectProj_Sampler2DRect1_Float3 =
+        TSymbolUniqueId(513);
+    static constexpr const TSymbolUniqueId texture2DRectProj_Sampler2DRect1_Float4 =
+        TSymbolUniqueId(514);
+    static constexpr const TSymbolUniqueId texture_Sampler2DRect1_Float2     = TSymbolUniqueId(515);
+    static constexpr const TSymbolUniqueId textureProj_Sampler2DRect1_Float3 = TSymbolUniqueId(516);
+    static constexpr const TSymbolUniqueId textureProj_Sampler2DRect1_Float4 = TSymbolUniqueId(517);
+    static constexpr const TSymbolUniqueId texture2DGradEXT_Sampler2D1_Float2_Float2_Float2 =
+        TSymbolUniqueId(518);
+    static constexpr const TSymbolUniqueId texture2DProjGradEXT_Sampler2D1_Float3_Float2_Float2 =
+        TSymbolUniqueId(519);
+    static constexpr const TSymbolUniqueId texture2DProjGradEXT_Sampler2D1_Float4_Float2_Float2 =
+        TSymbolUniqueId(520);
+    static constexpr const TSymbolUniqueId textureCubeGradEXT_SamplerCube1_Float3_Float3_Float3 =
+        TSymbolUniqueId(521);
+    static constexpr const TSymbolUniqueId texture2D_Sampler2D1_Float2_Float1 =
+        TSymbolUniqueId(522);
+    static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float3_Float1 =
+        TSymbolUniqueId(523);
+    static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float4_Float1 =
+        TSymbolUniqueId(524);
+    static constexpr const TSymbolUniqueId textureCube_SamplerCube1_Float3_Float1 =
+        TSymbolUniqueId(525);
+    static constexpr const TSymbolUniqueId dFdxExt_Float1   = TSymbolUniqueId(526);
+    static constexpr const TSymbolUniqueId dFdxExt_Float2   = TSymbolUniqueId(527);
+    static constexpr const TSymbolUniqueId dFdxExt_Float3   = TSymbolUniqueId(528);
+    static constexpr const TSymbolUniqueId dFdxExt_Float4   = TSymbolUniqueId(529);
+    static constexpr const TSymbolUniqueId dFdyExt_Float1   = TSymbolUniqueId(530);
+    static constexpr const TSymbolUniqueId dFdyExt_Float2   = TSymbolUniqueId(531);
+    static constexpr const TSymbolUniqueId dFdyExt_Float3   = TSymbolUniqueId(532);
+    static constexpr const TSymbolUniqueId dFdyExt_Float4   = TSymbolUniqueId(533);
+    static constexpr const TSymbolUniqueId fwidthExt_Float1 = TSymbolUniqueId(534);
+    static constexpr const TSymbolUniqueId fwidthExt_Float2 = TSymbolUniqueId(535);
+    static constexpr const TSymbolUniqueId fwidthExt_Float3 = TSymbolUniqueId(536);
+    static constexpr const TSymbolUniqueId fwidthExt_Float4 = TSymbolUniqueId(537);
+    static constexpr const TSymbolUniqueId texture2DLodEXT_Sampler2D1_Float2_Float1 =
+        TSymbolUniqueId(538);
+    static constexpr const TSymbolUniqueId texture2DProjLodEXT_Sampler2D1_Float3_Float1 =
+        TSymbolUniqueId(539);
+    static constexpr const TSymbolUniqueId texture2DProjLodEXT_Sampler2D1_Float4_Float1 =
+        TSymbolUniqueId(540);
+    static constexpr const TSymbolUniqueId textureCubeLodEXT_SamplerCube1_Float3_Float1 =
+        TSymbolUniqueId(541);
+    static constexpr const TSymbolUniqueId texture2DLod_Sampler2D1_Float2_Float1 =
+        TSymbolUniqueId(542);
+    static constexpr const TSymbolUniqueId texture2DProjLod_Sampler2D1_Float3_Float1 =
+        TSymbolUniqueId(543);
+    static constexpr const TSymbolUniqueId texture2DProjLod_Sampler2D1_Float4_Float1 =
+        TSymbolUniqueId(544);
+    static constexpr const TSymbolUniqueId textureCubeLod_SamplerCube1_Float3_Float1 =
+        TSymbolUniqueId(545);
+    static constexpr const TSymbolUniqueId texture_Sampler2D1_Float2       = TSymbolUniqueId(546);
+    static constexpr const TSymbolUniqueId texture_ISampler2D1_Float2      = TSymbolUniqueId(547);
+    static constexpr const TSymbolUniqueId pt0P                            = TSymbolUniqueId(548);
+    static constexpr const TSymbolUniqueId texture_USampler2D1_Float2      = TSymbolUniqueId(549);
+    static constexpr const TSymbolUniqueId pt0U                            = TSymbolUniqueId(550);
+    static constexpr const TSymbolUniqueId texture_Sampler3D1_Float3       = TSymbolUniqueId(551);
+    static constexpr const TSymbolUniqueId pt0I                            = TSymbolUniqueId(552);
+    static constexpr const TSymbolUniqueId texture_ISampler3D1_Float3      = TSymbolUniqueId(553);
+    static constexpr const TSymbolUniqueId pt0Q                            = TSymbolUniqueId(554);
+    static constexpr const TSymbolUniqueId texture_USampler3D1_Float3      = TSymbolUniqueId(555);
+    static constexpr const TSymbolUniqueId pt0V                            = TSymbolUniqueId(556);
+    static constexpr const TSymbolUniqueId texture_SamplerCube1_Float3     = TSymbolUniqueId(557);
+    static constexpr const TSymbolUniqueId texture_ISamplerCube1_Float3    = TSymbolUniqueId(558);
+    static constexpr const TSymbolUniqueId pt0R                            = TSymbolUniqueId(559);
+    static constexpr const TSymbolUniqueId texture_USamplerCube1_Float3    = TSymbolUniqueId(560);
+    static constexpr const TSymbolUniqueId pt0W                            = TSymbolUniqueId(561);
+    static constexpr const TSymbolUniqueId texture_Sampler2DArray1_Float3  = TSymbolUniqueId(562);
+    static constexpr const TSymbolUniqueId pt0K                            = TSymbolUniqueId(563);
+    static constexpr const TSymbolUniqueId texture_ISampler2DArray1_Float3 = TSymbolUniqueId(564);
+    static constexpr const TSymbolUniqueId pt0S                            = TSymbolUniqueId(565);
+    static constexpr const TSymbolUniqueId texture_USampler2DArray1_Float3 = TSymbolUniqueId(566);
+    static constexpr const TSymbolUniqueId pt0X                            = TSymbolUniqueId(567);
+    static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float3   = TSymbolUniqueId(568);
+    static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float3  = TSymbolUniqueId(569);
+    static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float3  = TSymbolUniqueId(570);
+    static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float4   = TSymbolUniqueId(571);
+    static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float4  = TSymbolUniqueId(572);
+    static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float4  = TSymbolUniqueId(573);
+    static constexpr const TSymbolUniqueId textureProj_Sampler3D1_Float4   = TSymbolUniqueId(574);
+    static constexpr const TSymbolUniqueId textureProj_ISampler3D1_Float4  = TSymbolUniqueId(575);
+    static constexpr const TSymbolUniqueId textureProj_USampler3D1_Float4  = TSymbolUniqueId(576);
+    static constexpr const TSymbolUniqueId textureLod_Sampler2D1_Float2_Float1 =
+        TSymbolUniqueId(577);
+    static constexpr const TSymbolUniqueId textureLod_ISampler2D1_Float2_Float1 =
+        TSymbolUniqueId(578);
+    static constexpr const TSymbolUniqueId textureLod_USampler2D1_Float2_Float1 =
+        TSymbolUniqueId(579);
+    static constexpr const TSymbolUniqueId textureLod_Sampler3D1_Float3_Float1 =
+        TSymbolUniqueId(580);
+    static constexpr const TSymbolUniqueId textureLod_ISampler3D1_Float3_Float1 =
+        TSymbolUniqueId(581);
+    static constexpr const TSymbolUniqueId textureLod_USampler3D1_Float3_Float1 =
+        TSymbolUniqueId(582);
+    static constexpr const TSymbolUniqueId textureLod_SamplerCube1_Float3_Float1 =
+        TSymbolUniqueId(583);
+    static constexpr const TSymbolUniqueId textureLod_ISamplerCube1_Float3_Float1 =
+        TSymbolUniqueId(584);
+    static constexpr const TSymbolUniqueId textureLod_USamplerCube1_Float3_Float1 =
+        TSymbolUniqueId(585);
+    static constexpr const TSymbolUniqueId textureLod_Sampler2DArray1_Float3_Float1 =
+        TSymbolUniqueId(586);
+    static constexpr const TSymbolUniqueId textureLod_ISampler2DArray1_Float3_Float1 =
+        TSymbolUniqueId(587);
+    static constexpr const TSymbolUniqueId textureLod_USampler2DArray1_Float3_Float1 =
+        TSymbolUniqueId(588);
+    static constexpr const TSymbolUniqueId texture_Sampler2DShadow1_Float3   = TSymbolUniqueId(589);
+    static constexpr const TSymbolUniqueId pt0Z                              = TSymbolUniqueId(590);
+    static constexpr const TSymbolUniqueId texture_SamplerCubeShadow1_Float4 = TSymbolUniqueId(591);
+    static constexpr const TSymbolUniqueId pt0a                              = TSymbolUniqueId(592);
+    static constexpr const TSymbolUniqueId texture_Sampler2DArrayShadow1_Float4 =
+        TSymbolUniqueId(593);
+    static constexpr const TSymbolUniqueId pt0b = TSymbolUniqueId(594);
+    static constexpr const TSymbolUniqueId textureProj_Sampler2DShadow1_Float4 =
+        TSymbolUniqueId(595);
+    static constexpr const TSymbolUniqueId textureLod_Sampler2DShadow1_Float3_Float1 =
+        TSymbolUniqueId(596);
+    static constexpr const TSymbolUniqueId textureSize_Sampler2D1_Int1       = TSymbolUniqueId(597);
+    static constexpr const TSymbolUniqueId textureSize_ISampler2D1_Int1      = TSymbolUniqueId(598);
+    static constexpr const TSymbolUniqueId textureSize_USampler2D1_Int1      = TSymbolUniqueId(599);
+    static constexpr const TSymbolUniqueId textureSize_Sampler3D1_Int1       = TSymbolUniqueId(600);
+    static constexpr const TSymbolUniqueId textureSize_ISampler3D1_Int1      = TSymbolUniqueId(601);
+    static constexpr const TSymbolUniqueId textureSize_USampler3D1_Int1      = TSymbolUniqueId(602);
+    static constexpr const TSymbolUniqueId textureSize_SamplerCube1_Int1     = TSymbolUniqueId(603);
+    static constexpr const TSymbolUniqueId textureSize_ISamplerCube1_Int1    = TSymbolUniqueId(604);
+    static constexpr const TSymbolUniqueId textureSize_USamplerCube1_Int1    = TSymbolUniqueId(605);
+    static constexpr const TSymbolUniqueId textureSize_Sampler2DArray1_Int1  = TSymbolUniqueId(606);
+    static constexpr const TSymbolUniqueId textureSize_ISampler2DArray1_Int1 = TSymbolUniqueId(607);
+    static constexpr const TSymbolUniqueId textureSize_USampler2DArray1_Int1 = TSymbolUniqueId(608);
+    static constexpr const TSymbolUniqueId textureSize_Sampler2DShadow1_Int1 = TSymbolUniqueId(609);
+    static constexpr const TSymbolUniqueId textureSize_SamplerCubeShadow1_Int1 =
+        TSymbolUniqueId(610);
+    static constexpr const TSymbolUniqueId textureSize_Sampler2DArrayShadow1_Int1 =
+        TSymbolUniqueId(611);
+    static constexpr const TSymbolUniqueId textureSize_Sampler2DMS1  = TSymbolUniqueId(612);
+    static constexpr const TSymbolUniqueId pt0O                      = TSymbolUniqueId(613);
+    static constexpr const TSymbolUniqueId textureSize_ISampler2DMS1 = TSymbolUniqueId(614);
+    static constexpr const TSymbolUniqueId pt0T                      = TSymbolUniqueId(615);
+    static constexpr const TSymbolUniqueId textureSize_USampler2DMS1 = TSymbolUniqueId(616);
+    static constexpr const TSymbolUniqueId pt0Y                      = TSymbolUniqueId(617);
+    static constexpr const TSymbolUniqueId textureProjLod_Sampler2D1_Float3_Float1 =
+        TSymbolUniqueId(618);
+    static constexpr const TSymbolUniqueId textureProjLod_ISampler2D1_Float3_Float1 =
+        TSymbolUniqueId(619);
+    static constexpr const TSymbolUniqueId textureProjLod_USampler2D1_Float3_Float1 =
+        TSymbolUniqueId(620);
+    static constexpr const TSymbolUniqueId textureProjLod_Sampler2D1_Float4_Float1 =
+        TSymbolUniqueId(621);
+    static constexpr const TSymbolUniqueId textureProjLod_ISampler2D1_Float4_Float1 =
+        TSymbolUniqueId(622);
+    static constexpr const TSymbolUniqueId textureProjLod_USampler2D1_Float4_Float1 =
+        TSymbolUniqueId(623);
+    static constexpr const TSymbolUniqueId textureProjLod_Sampler3D1_Float4_Float1 =
+        TSymbolUniqueId(624);
+    static constexpr const TSymbolUniqueId textureProjLod_ISampler3D1_Float4_Float1 =
+        TSymbolUniqueId(625);
+    static constexpr const TSymbolUniqueId textureProjLod_USampler3D1_Float4_Float1 =
+        TSymbolUniqueId(626);
+    static constexpr const TSymbolUniqueId textureProjLod_Sampler2DShadow1_Float4_Float1 =
+        TSymbolUniqueId(627);
+    static constexpr const TSymbolUniqueId texelFetch_Sampler2D1_Int2_Int1  = TSymbolUniqueId(628);
+    static constexpr const TSymbolUniqueId texelFetch_ISampler2D1_Int2_Int1 = TSymbolUniqueId(629);
+    static constexpr const TSymbolUniqueId texelFetch_USampler2D1_Int2_Int1 = TSymbolUniqueId(630);
+    static constexpr const TSymbolUniqueId texelFetch_Sampler3D1_Int3_Int1  = TSymbolUniqueId(631);
+    static constexpr const TSymbolUniqueId texelFetch_ISampler3D1_Int3_Int1 = TSymbolUniqueId(632);
+    static constexpr const TSymbolUniqueId texelFetch_USampler3D1_Int3_Int1 = TSymbolUniqueId(633);
+    static constexpr const TSymbolUniqueId texelFetch_Sampler2DArray1_Int3_Int1 =
+        TSymbolUniqueId(634);
+    static constexpr const TSymbolUniqueId texelFetch_ISampler2DArray1_Int3_Int1 =
+        TSymbolUniqueId(635);
+    static constexpr const TSymbolUniqueId texelFetch_USampler2DArray1_Int3_Int1 =
+        TSymbolUniqueId(636);
+    static constexpr const TSymbolUniqueId textureGrad_Sampler2D1_Float2_Float2_Float2 =
+        TSymbolUniqueId(637);
+    static constexpr const TSymbolUniqueId textureGrad_ISampler2D1_Float2_Float2_Float2 =
+        TSymbolUniqueId(638);
+    static constexpr const TSymbolUniqueId textureGrad_USampler2D1_Float2_Float2_Float2 =
+        TSymbolUniqueId(639);
+    static constexpr const TSymbolUniqueId textureGrad_Sampler3D1_Float3_Float3_Float3 =
+        TSymbolUniqueId(640);
+    static constexpr const TSymbolUniqueId textureGrad_ISampler3D1_Float3_Float3_Float3 =
+        TSymbolUniqueId(641);
+    static constexpr const TSymbolUniqueId textureGrad_USampler3D1_Float3_Float3_Float3 =
+        TSymbolUniqueId(642);
+    static constexpr const TSymbolUniqueId textureGrad_SamplerCube1_Float3_Float3_Float3 =
+        TSymbolUniqueId(643);
+    static constexpr const TSymbolUniqueId textureGrad_ISamplerCube1_Float3_Float3_Float3 =
+        TSymbolUniqueId(644);
+    static constexpr const TSymbolUniqueId textureGrad_USamplerCube1_Float3_Float3_Float3 =
+        TSymbolUniqueId(645);
+    static constexpr const TSymbolUniqueId textureGrad_Sampler2DShadow1_Float3_Float2_Float2 =
+        TSymbolUniqueId(646);
+    static constexpr const TSymbolUniqueId textureGrad_SamplerCubeShadow1_Float4_Float3_Float3 =
+        TSymbolUniqueId(647);
+    static constexpr const TSymbolUniqueId textureGrad_Sampler2DArray1_Float3_Float2_Float2 =
+        TSymbolUniqueId(648);
+    static constexpr const TSymbolUniqueId textureGrad_ISampler2DArray1_Float3_Float2_Float2 =
+        TSymbolUniqueId(649);
+    static constexpr const TSymbolUniqueId textureGrad_USampler2DArray1_Float3_Float2_Float2 =
+        TSymbolUniqueId(650);
+    static constexpr const TSymbolUniqueId textureGrad_Sampler2DArrayShadow1_Float4_Float2_Float2 =
+        TSymbolUniqueId(651);
+    static constexpr const TSymbolUniqueId textureProjGrad_Sampler2D1_Float3_Float2_Float2 =
+        TSymbolUniqueId(652);
+    static constexpr const TSymbolUniqueId textureProjGrad_ISampler2D1_Float3_Float2_Float2 =
+        TSymbolUniqueId(653);
+    static constexpr const TSymbolUniqueId textureProjGrad_USampler2D1_Float3_Float2_Float2 =
+        TSymbolUniqueId(654);
+    static constexpr const TSymbolUniqueId textureProjGrad_Sampler2D1_Float4_Float2_Float2 =
+        TSymbolUniqueId(655);
+    static constexpr const TSymbolUniqueId textureProjGrad_ISampler2D1_Float4_Float2_Float2 =
+        TSymbolUniqueId(656);
+    static constexpr const TSymbolUniqueId textureProjGrad_USampler2D1_Float4_Float2_Float2 =
+        TSymbolUniqueId(657);
+    static constexpr const TSymbolUniqueId textureProjGrad_Sampler3D1_Float4_Float3_Float3 =
+        TSymbolUniqueId(658);
+    static constexpr const TSymbolUniqueId textureProjGrad_ISampler3D1_Float4_Float3_Float3 =
+        TSymbolUniqueId(659);
+    static constexpr const TSymbolUniqueId textureProjGrad_USampler3D1_Float4_Float3_Float3 =
+        TSymbolUniqueId(660);
+    static constexpr const TSymbolUniqueId textureProjGrad_Sampler2DShadow1_Float4_Float2_Float2 =
+        TSymbolUniqueId(661);
+    static constexpr const TSymbolUniqueId textureOffset_Sampler2D1_Float2_Int2 =
+        TSymbolUniqueId(662);
+    static constexpr const TSymbolUniqueId textureOffset_ISampler2D1_Float2_Int2 =
+        TSymbolUniqueId(663);
+    static constexpr const TSymbolUniqueId textureOffset_USampler2D1_Float2_Int2 =
+        TSymbolUniqueId(664);
+    static constexpr const TSymbolUniqueId textureOffset_Sampler3D1_Float3_Int3 =
+        TSymbolUniqueId(665);
+    static constexpr const TSymbolUniqueId textureOffset_ISampler3D1_Float3_Int3 =
+        TSymbolUniqueId(666);
+    static constexpr const TSymbolUniqueId textureOffset_USampler3D1_Float3_Int3 =
+        TSymbolUniqueId(667);
+    static constexpr const TSymbolUniqueId textureOffset_Sampler2DShadow1_Float3_Int2 =
+        TSymbolUniqueId(668);
+    static constexpr const TSymbolUniqueId textureOffset_Sampler2DArray1_Float3_Int2 =
+        TSymbolUniqueId(669);
+    static constexpr const TSymbolUniqueId textureOffset_ISampler2DArray1_Float3_Int2 =
+        TSymbolUniqueId(670);
+    static constexpr const TSymbolUniqueId textureOffset_USampler2DArray1_Float3_Int2 =
+        TSymbolUniqueId(671);
+    static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float3_Int2 =
+        TSymbolUniqueId(672);
+    static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float3_Int2 =
+        TSymbolUniqueId(673);
+    static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float3_Int2 =
+        TSymbolUniqueId(674);
+    static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float4_Int2 =
+        TSymbolUniqueId(675);
+    static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float4_Int2 =
+        TSymbolUniqueId(676);
+    static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float4_Int2 =
+        TSymbolUniqueId(677);
+    static constexpr const TSymbolUniqueId textureProjOffset_Sampler3D1_Float4_Int3 =
+        TSymbolUniqueId(678);
+    static constexpr const TSymbolUniqueId textureProjOffset_ISampler3D1_Float4_Int3 =
+        TSymbolUniqueId(679);
+    static constexpr const TSymbolUniqueId textureProjOffset_USampler3D1_Float4_Int3 =
+        TSymbolUniqueId(680);
+    static constexpr const TSymbolUniqueId textureProjOffset_Sampler2DShadow1_Float4_Int2 =
+        TSymbolUniqueId(681);
+    static constexpr const TSymbolUniqueId textureLodOffset_Sampler2D1_Float2_Float1_Int2 =
+        TSymbolUniqueId(682);
+    static constexpr const TSymbolUniqueId textureLodOffset_ISampler2D1_Float2_Float1_Int2 =
+        TSymbolUniqueId(683);
+    static constexpr const TSymbolUniqueId textureLodOffset_USampler2D1_Float2_Float1_Int2 =
+        TSymbolUniqueId(684);
+    static constexpr const TSymbolUniqueId textureLodOffset_Sampler3D1_Float3_Float1_Int3 =
+        TSymbolUniqueId(685);
+    static constexpr const TSymbolUniqueId textureLodOffset_ISampler3D1_Float3_Float1_Int3 =
+        TSymbolUniqueId(686);
+    static constexpr const TSymbolUniqueId textureLodOffset_USampler3D1_Float3_Float1_Int3 =
+        TSymbolUniqueId(687);
+    static constexpr const TSymbolUniqueId textureLodOffset_Sampler2DShadow1_Float3_Float1_Int2 =
+        TSymbolUniqueId(688);
+    static constexpr const TSymbolUniqueId textureLodOffset_Sampler2DArray1_Float3_Float1_Int2 =
+        TSymbolUniqueId(689);
+    static constexpr const TSymbolUniqueId textureLodOffset_ISampler2DArray1_Float3_Float1_Int2 =
+        TSymbolUniqueId(690);
+    static constexpr const TSymbolUniqueId textureLodOffset_USampler2DArray1_Float3_Float1_Int2 =
+        TSymbolUniqueId(691);
+    static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler2D1_Float3_Float1_Int2 =
+        TSymbolUniqueId(692);
+    static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler2D1_Float3_Float1_Int2 =
+        TSymbolUniqueId(693);
+    static constexpr const TSymbolUniqueId textureProjLodOffset_USampler2D1_Float3_Float1_Int2 =
+        TSymbolUniqueId(694);
+    static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler2D1_Float4_Float1_Int2 =
+        TSymbolUniqueId(695);
+    static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler2D1_Float4_Float1_Int2 =
+        TSymbolUniqueId(696);
+    static constexpr const TSymbolUniqueId textureProjLodOffset_USampler2D1_Float4_Float1_Int2 =
+        TSymbolUniqueId(697);
+    static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler3D1_Float4_Float1_Int3 =
+        TSymbolUniqueId(698);
+    static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler3D1_Float4_Float1_Int3 =
+        TSymbolUniqueId(699);
+    static constexpr const TSymbolUniqueId textureProjLodOffset_USampler3D1_Float4_Float1_Int3 =
+        TSymbolUniqueId(700);
+    static constexpr const TSymbolUniqueId
+        textureProjLodOffset_Sampler2DShadow1_Float4_Float1_Int2 = TSymbolUniqueId(701);
+    static constexpr const TSymbolUniqueId texelFetchOffset_Sampler2D1_Int2_Int1_Int2 =
+        TSymbolUniqueId(702);
+    static constexpr const TSymbolUniqueId texelFetchOffset_ISampler2D1_Int2_Int1_Int2 =
+        TSymbolUniqueId(703);
+    static constexpr const TSymbolUniqueId texelFetchOffset_USampler2D1_Int2_Int1_Int2 =
+        TSymbolUniqueId(704);
+    static constexpr const TSymbolUniqueId texelFetchOffset_Sampler3D1_Int3_Int1_Int3 =
+        TSymbolUniqueId(705);
+    static constexpr const TSymbolUniqueId texelFetchOffset_ISampler3D1_Int3_Int1_Int3 =
+        TSymbolUniqueId(706);
+    static constexpr const TSymbolUniqueId texelFetchOffset_USampler3D1_Int3_Int1_Int3 =
+        TSymbolUniqueId(707);
+    static constexpr const TSymbolUniqueId texelFetchOffset_Sampler2DArray1_Int3_Int1_Int2 =
+        TSymbolUniqueId(708);
+    static constexpr const TSymbolUniqueId texelFetchOffset_ISampler2DArray1_Int3_Int1_Int2 =
+        TSymbolUniqueId(709);
+    static constexpr const TSymbolUniqueId texelFetchOffset_USampler2DArray1_Int3_Int1_Int2 =
+        TSymbolUniqueId(710);
+    static constexpr const TSymbolUniqueId textureGradOffset_Sampler2D1_Float2_Float2_Float2_Int2 =
+        TSymbolUniqueId(711);
+    static constexpr const TSymbolUniqueId textureGradOffset_ISampler2D1_Float2_Float2_Float2_Int2 =
+        TSymbolUniqueId(712);
+    static constexpr const TSymbolUniqueId textureGradOffset_USampler2D1_Float2_Float2_Float2_Int2 =
+        TSymbolUniqueId(713);
+    static constexpr const TSymbolUniqueId textureGradOffset_Sampler3D1_Float3_Float3_Float3_Int3 =
+        TSymbolUniqueId(714);
+    static constexpr const TSymbolUniqueId textureGradOffset_ISampler3D1_Float3_Float3_Float3_Int3 =
+        TSymbolUniqueId(715);
+    static constexpr const TSymbolUniqueId textureGradOffset_USampler3D1_Float3_Float3_Float3_Int3 =
+        TSymbolUniqueId(716);
+    static constexpr const TSymbolUniqueId
+        textureGradOffset_Sampler2DShadow1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(717);
+    static constexpr const TSymbolUniqueId
+        textureGradOffset_Sampler2DArray1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(718);
+    static constexpr const TSymbolUniqueId
+        textureGradOffset_ISampler2DArray1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(719);
+    static constexpr const TSymbolUniqueId
+        textureGradOffset_USampler2DArray1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(720);
+    static constexpr const TSymbolUniqueId
+        textureGradOffset_Sampler2DArrayShadow1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(721);
+    static constexpr const TSymbolUniqueId
+        textureProjGradOffset_Sampler2D1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(722);
+    static constexpr const TSymbolUniqueId
+        textureProjGradOffset_ISampler2D1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(723);
+    static constexpr const TSymbolUniqueId
+        textureProjGradOffset_USampler2D1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(724);
+    static constexpr const TSymbolUniqueId
+        textureProjGradOffset_Sampler2D1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(725);
+    static constexpr const TSymbolUniqueId
+        textureProjGradOffset_ISampler2D1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(726);
+    static constexpr const TSymbolUniqueId
+        textureProjGradOffset_USampler2D1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(727);
+    static constexpr const TSymbolUniqueId
+        textureProjGradOffset_Sampler3D1_Float4_Float3_Float3_Int3 = TSymbolUniqueId(728);
+    static constexpr const TSymbolUniqueId
+        textureProjGradOffset_ISampler3D1_Float4_Float3_Float3_Int3 = TSymbolUniqueId(729);
+    static constexpr const TSymbolUniqueId
+        textureProjGradOffset_USampler3D1_Float4_Float3_Float3_Int3 = TSymbolUniqueId(730);
+    static constexpr const TSymbolUniqueId
+        textureProjGradOffset_Sampler2DShadow1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(731);
+    static constexpr const TSymbolUniqueId textureOffset_Sampler2D1_Float2_Int2_Float1 =
+        TSymbolUniqueId(732);
+    static constexpr const TSymbolUniqueId textureOffset_ISampler2D1_Float2_Int2_Float1 =
+        TSymbolUniqueId(733);
+    static constexpr const TSymbolUniqueId textureOffset_USampler2D1_Float2_Int2_Float1 =
+        TSymbolUniqueId(734);
+    static constexpr const TSymbolUniqueId textureOffset_Sampler3D1_Float3_Int3_Float1 =
+        TSymbolUniqueId(735);
+    static constexpr const TSymbolUniqueId textureOffset_ISampler3D1_Float3_Int3_Float1 =
+        TSymbolUniqueId(736);
+    static constexpr const TSymbolUniqueId textureOffset_USampler3D1_Float3_Int3_Float1 =
+        TSymbolUniqueId(737);
+    static constexpr const TSymbolUniqueId textureOffset_Sampler2DShadow1_Float3_Int2_Float1 =
+        TSymbolUniqueId(738);
+    static constexpr const TSymbolUniqueId textureOffset_Sampler2DArray1_Float3_Int2_Float1 =
+        TSymbolUniqueId(739);
+    static constexpr const TSymbolUniqueId textureOffset_ISampler2DArray1_Float3_Int2_Float1 =
+        TSymbolUniqueId(740);
+    static constexpr const TSymbolUniqueId textureOffset_USampler2DArray1_Float3_Int2_Float1 =
+        TSymbolUniqueId(741);
+    static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float3_Int2_Float1 =
+        TSymbolUniqueId(742);
+    static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float3_Int2_Float1 =
+        TSymbolUniqueId(743);
+    static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float3_Int2_Float1 =
+        TSymbolUniqueId(744);
+    static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float4_Int2_Float1 =
+        TSymbolUniqueId(745);
+    static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float4_Int2_Float1 =
+        TSymbolUniqueId(746);
+    static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float4_Int2_Float1 =
+        TSymbolUniqueId(747);
+    static constexpr const TSymbolUniqueId textureProjOffset_Sampler3D1_Float4_Int3_Float1 =
+        TSymbolUniqueId(748);
+    static constexpr const TSymbolUniqueId textureProjOffset_ISampler3D1_Float4_Int3_Float1 =
+        TSymbolUniqueId(749);
+    static constexpr const TSymbolUniqueId textureProjOffset_USampler3D1_Float4_Int3_Float1 =
+        TSymbolUniqueId(750);
+    static constexpr const TSymbolUniqueId textureProjOffset_Sampler2DShadow1_Float4_Int2_Float1 =
+        TSymbolUniqueId(751);
+    static constexpr const TSymbolUniqueId texture_SamplerExternalOES1_Float2 =
+        TSymbolUniqueId(752);
+    static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float3 =
+        TSymbolUniqueId(753);
+    static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float4 =
+        TSymbolUniqueId(754);
+    static constexpr const TSymbolUniqueId textureSize_SamplerExternalOES1_Int1 =
+        TSymbolUniqueId(755);
+    static constexpr const TSymbolUniqueId texelFetch_SamplerExternalOES1_Int2_Int1 =
+        TSymbolUniqueId(756);
+    static constexpr const TSymbolUniqueId texture_SamplerExternal2DY2YEXT1_Float2 =
+        TSymbolUniqueId(757);
+    static constexpr const TSymbolUniqueId pt0M = TSymbolUniqueId(758);
+    static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float3 =
+        TSymbolUniqueId(759);
+    static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float4 =
+        TSymbolUniqueId(760);
+    static constexpr const TSymbolUniqueId rgb_2_yuv_Float3_YuvCscStandardEXT1 =
+        TSymbolUniqueId(761);
+    static constexpr const TSymbolUniqueId pt0G = TSymbolUniqueId(762);
+    static constexpr const TSymbolUniqueId yuv_2_rgb_Float3_YuvCscStandardEXT1 =
+        TSymbolUniqueId(763);
+    static constexpr const TSymbolUniqueId textureSize_SamplerExternal2DY2YEXT1_Int1 =
+        TSymbolUniqueId(764);
+    static constexpr const TSymbolUniqueId texelFetch_SamplerExternal2DY2YEXT1_Int2_Int1 =
+        TSymbolUniqueId(765);
+    static constexpr const TSymbolUniqueId texture_Sampler2D1_Float2_Float1  = TSymbolUniqueId(766);
+    static constexpr const TSymbolUniqueId texture_ISampler2D1_Float2_Float1 = TSymbolUniqueId(767);
+    static constexpr const TSymbolUniqueId texture_USampler2D1_Float2_Float1 = TSymbolUniqueId(768);
+    static constexpr const TSymbolUniqueId texture_Sampler3D1_Float3_Float1  = TSymbolUniqueId(769);
+    static constexpr const TSymbolUniqueId texture_ISampler3D1_Float3_Float1 = TSymbolUniqueId(770);
+    static constexpr const TSymbolUniqueId texture_USampler3D1_Float3_Float1 = TSymbolUniqueId(771);
+    static constexpr const TSymbolUniqueId texture_SamplerCube1_Float3_Float1 =
+        TSymbolUniqueId(772);
+    static constexpr const TSymbolUniqueId texture_ISamplerCube1_Float3_Float1 =
+        TSymbolUniqueId(773);
+    static constexpr const TSymbolUniqueId texture_USamplerCube1_Float3_Float1 =
+        TSymbolUniqueId(774);
+    static constexpr const TSymbolUniqueId texture_Sampler2DArray1_Float3_Float1 =
+        TSymbolUniqueId(775);
+    static constexpr const TSymbolUniqueId texture_ISampler2DArray1_Float3_Float1 =
+        TSymbolUniqueId(776);
+    static constexpr const TSymbolUniqueId texture_USampler2DArray1_Float3_Float1 =
+        TSymbolUniqueId(777);
+    static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float3_Float1 =
+        TSymbolUniqueId(778);
+    static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float3_Float1 =
+        TSymbolUniqueId(779);
+    static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float3_Float1 =
+        TSymbolUniqueId(780);
+    static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float4_Float1 =
+        TSymbolUniqueId(781);
+    static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float4_Float1 =
+        TSymbolUniqueId(782);
+    static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float4_Float1 =
+        TSymbolUniqueId(783);
+    static constexpr const TSymbolUniqueId textureProj_Sampler3D1_Float4_Float1 =
+        TSymbolUniqueId(784);
+    static constexpr const TSymbolUniqueId textureProj_ISampler3D1_Float4_Float1 =
+        TSymbolUniqueId(785);
+    static constexpr const TSymbolUniqueId textureProj_USampler3D1_Float4_Float1 =
+        TSymbolUniqueId(786);
+    static constexpr const TSymbolUniqueId texture_Sampler2DShadow1_Float3_Float1 =
+        TSymbolUniqueId(787);
+    static constexpr const TSymbolUniqueId texture_SamplerCubeShadow1_Float4_Float1 =
+        TSymbolUniqueId(788);
+    static constexpr const TSymbolUniqueId textureProj_Sampler2DShadow1_Float4_Float1 =
+        TSymbolUniqueId(789);
+    static constexpr const TSymbolUniqueId texture_SamplerExternalOES1_Float2_Float1 =
+        TSymbolUniqueId(790);
+    static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float3_Float1 =
+        TSymbolUniqueId(791);
+    static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float4_Float1 =
+        TSymbolUniqueId(792);
+    static constexpr const TSymbolUniqueId texture_SamplerExternal2DY2YEXT1_Float2_Float1 =
+        TSymbolUniqueId(793);
+    static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float3_Float1 =
+        TSymbolUniqueId(794);
+    static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float4_Float1 =
+        TSymbolUniqueId(795);
+    static constexpr const TSymbolUniqueId texelFetch_Sampler2DMS1_Int2_Int1 = TSymbolUniqueId(796);
+    static constexpr const TSymbolUniqueId texelFetch_ISampler2DMS1_Int2_Int1 =
+        TSymbolUniqueId(797);
+    static constexpr const TSymbolUniqueId texelFetch_USampler2DMS1_Int2_Int1 =
+        TSymbolUniqueId(798);
+    static constexpr const TSymbolUniqueId textureGather_Sampler2D1_Float2  = TSymbolUniqueId(799);
+    static constexpr const TSymbolUniqueId textureGather_ISampler2D1_Float2 = TSymbolUniqueId(800);
+    static constexpr const TSymbolUniqueId textureGather_USampler2D1_Float2 = TSymbolUniqueId(801);
+    static constexpr const TSymbolUniqueId textureGather_Sampler2D1_Float2_Int1 =
+        TSymbolUniqueId(802);
+    static constexpr const TSymbolUniqueId textureGather_ISampler2D1_Float2_Int1 =
+        TSymbolUniqueId(803);
+    static constexpr const TSymbolUniqueId textureGather_USampler2D1_Float2_Int1 =
+        TSymbolUniqueId(804);
+    static constexpr const TSymbolUniqueId textureGather_Sampler2DArray1_Float3 =
+        TSymbolUniqueId(805);
+    static constexpr const TSymbolUniqueId textureGather_ISampler2DArray1_Float3 =
+        TSymbolUniqueId(806);
+    static constexpr const TSymbolUniqueId textureGather_USampler2DArray1_Float3 =
+        TSymbolUniqueId(807);
+    static constexpr const TSymbolUniqueId textureGather_Sampler2DArray1_Float3_Int1 =
+        TSymbolUniqueId(808);
+    static constexpr const TSymbolUniqueId textureGather_ISampler2DArray1_Float3_Int1 =
+        TSymbolUniqueId(809);
+    static constexpr const TSymbolUniqueId textureGather_USampler2DArray1_Float3_Int1 =
+        TSymbolUniqueId(810);
+    static constexpr const TSymbolUniqueId textureGather_SamplerCube1_Float3 = TSymbolUniqueId(811);
+    static constexpr const TSymbolUniqueId textureGather_ISamplerCube1_Float3 =
+        TSymbolUniqueId(812);
+    static constexpr const TSymbolUniqueId textureGather_USamplerCube1_Float3 =
+        TSymbolUniqueId(813);
+    static constexpr const TSymbolUniqueId textureGather_SamplerCube1_Float3_Int1 =
+        TSymbolUniqueId(814);
+    static constexpr const TSymbolUniqueId textureGather_ISamplerCube1_Float3_Int1 =
+        TSymbolUniqueId(815);
+    static constexpr const TSymbolUniqueId textureGather_USamplerCube1_Float3_Int1 =
+        TSymbolUniqueId(816);
+    static constexpr const TSymbolUniqueId textureGather_Sampler2DShadow1_Float2 =
+        TSymbolUniqueId(817);
+    static constexpr const TSymbolUniqueId textureGather_Sampler2DShadow1_Float2_Float1 =
+        TSymbolUniqueId(818);
+    static constexpr const TSymbolUniqueId textureGather_Sampler2DArrayShadow1_Float3 =
+        TSymbolUniqueId(819);
+    static constexpr const TSymbolUniqueId textureGather_Sampler2DArrayShadow1_Float3_Float1 =
+        TSymbolUniqueId(820);
+    static constexpr const TSymbolUniqueId textureGather_SamplerCubeShadow1_Float3 =
+        TSymbolUniqueId(821);
+    static constexpr const TSymbolUniqueId textureGather_SamplerCubeShadow1_Float3_Float1 =
+        TSymbolUniqueId(822);
+    static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2D1_Float2_Int2 =
+        TSymbolUniqueId(823);
+    static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2D1_Float2_Int2 =
+        TSymbolUniqueId(824);
+    static constexpr const TSymbolUniqueId textureGatherOffset_USampler2D1_Float2_Int2 =
+        TSymbolUniqueId(825);
+    static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2D1_Float2_Int2_Int1 =
+        TSymbolUniqueId(826);
+    static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2D1_Float2_Int2_Int1 =
+        TSymbolUniqueId(827);
+    static constexpr const TSymbolUniqueId textureGatherOffset_USampler2D1_Float2_Int2_Int1 =
+        TSymbolUniqueId(828);
+    static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DArray1_Float3_Int2 =
+        TSymbolUniqueId(829);
+    static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2DArray1_Float3_Int2 =
+        TSymbolUniqueId(830);
+    static constexpr const TSymbolUniqueId textureGatherOffset_USampler2DArray1_Float3_Int2 =
+        TSymbolUniqueId(831);
+    static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DArray1_Float3_Int2_Int1 =
+        TSymbolUniqueId(832);
+    static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2DArray1_Float3_Int2_Int1 =
+        TSymbolUniqueId(833);
+    static constexpr const TSymbolUniqueId textureGatherOffset_USampler2DArray1_Float3_Int2_Int1 =
+        TSymbolUniqueId(834);
+    static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DShadow1_Float2_Float1_Int2 =
+        TSymbolUniqueId(835);
+    static constexpr const TSymbolUniqueId
+        textureGatherOffset_Sampler2DArrayShadow1_Float3_Float1_Int2    = TSymbolUniqueId(836);
+    static constexpr const TSymbolUniqueId dFdx_Float1                  = TSymbolUniqueId(837);
+    static constexpr const TSymbolUniqueId dFdx_Float2                  = TSymbolUniqueId(838);
+    static constexpr const TSymbolUniqueId dFdx_Float3                  = TSymbolUniqueId(839);
+    static constexpr const TSymbolUniqueId dFdx_Float4                  = TSymbolUniqueId(840);
+    static constexpr const TSymbolUniqueId dFdy_Float1                  = TSymbolUniqueId(841);
+    static constexpr const TSymbolUniqueId dFdy_Float2                  = TSymbolUniqueId(842);
+    static constexpr const TSymbolUniqueId dFdy_Float3                  = TSymbolUniqueId(843);
+    static constexpr const TSymbolUniqueId dFdy_Float4                  = TSymbolUniqueId(844);
+    static constexpr const TSymbolUniqueId fwidth_Float1                = TSymbolUniqueId(845);
+    static constexpr const TSymbolUniqueId fwidth_Float2                = TSymbolUniqueId(846);
+    static constexpr const TSymbolUniqueId fwidth_Float3                = TSymbolUniqueId(847);
+    static constexpr const TSymbolUniqueId fwidth_Float4                = TSymbolUniqueId(848);
+    static constexpr const TSymbolUniqueId atomicCounter_AtomicCounter1 = TSymbolUniqueId(849);
+    static constexpr const TSymbolUniqueId pt0F                         = TSymbolUniqueId(850);
+    static constexpr const TSymbolUniqueId atomicCounterIncrement_AtomicCounter1 =
+        TSymbolUniqueId(851);
+    static constexpr const TSymbolUniqueId atomicCounterDecrement_AtomicCounter1 =
+        TSymbolUniqueId(852);
+    static constexpr const TSymbolUniqueId atomicAdd_UInt1_UInt1            = TSymbolUniqueId(853);
+    static constexpr const TSymbolUniqueId pt_io_0D                         = TSymbolUniqueId(854);
+    static constexpr const TSymbolUniqueId atomicAdd_Int1_Int1              = TSymbolUniqueId(855);
+    static constexpr const TSymbolUniqueId pt_io_0C                         = TSymbolUniqueId(856);
+    static constexpr const TSymbolUniqueId atomicMin_UInt1_UInt1            = TSymbolUniqueId(857);
+    static constexpr const TSymbolUniqueId atomicMin_Int1_Int1              = TSymbolUniqueId(858);
+    static constexpr const TSymbolUniqueId atomicMax_UInt1_UInt1            = TSymbolUniqueId(859);
+    static constexpr const TSymbolUniqueId atomicMax_Int1_Int1              = TSymbolUniqueId(860);
+    static constexpr const TSymbolUniqueId atomicAnd_UInt1_UInt1            = TSymbolUniqueId(861);
+    static constexpr const TSymbolUniqueId atomicAnd_Int1_Int1              = TSymbolUniqueId(862);
+    static constexpr const TSymbolUniqueId atomicOr_UInt1_UInt1             = TSymbolUniqueId(863);
+    static constexpr const TSymbolUniqueId atomicOr_Int1_Int1               = TSymbolUniqueId(864);
+    static constexpr const TSymbolUniqueId atomicXor_UInt1_UInt1            = TSymbolUniqueId(865);
+    static constexpr const TSymbolUniqueId atomicXor_Int1_Int1              = TSymbolUniqueId(866);
+    static constexpr const TSymbolUniqueId atomicExchange_UInt1_UInt1       = TSymbolUniqueId(867);
+    static constexpr const TSymbolUniqueId atomicExchange_Int1_Int1         = TSymbolUniqueId(868);
+    static constexpr const TSymbolUniqueId atomicCompSwap_UInt1_UInt1_UInt1 = TSymbolUniqueId(869);
+    static constexpr const TSymbolUniqueId atomicCompSwap_Int1_Int1_Int1    = TSymbolUniqueId(870);
+    static constexpr const TSymbolUniqueId imageSize_Image2D1               = TSymbolUniqueId(871);
+    static constexpr const TSymbolUniqueId pt0c                             = TSymbolUniqueId(872);
+    static constexpr const TSymbolUniqueId imageSize_IImage2D1              = TSymbolUniqueId(873);
+    static constexpr const TSymbolUniqueId pt0d                             = TSymbolUniqueId(874);
+    static constexpr const TSymbolUniqueId imageSize_UImage2D1              = TSymbolUniqueId(875);
+    static constexpr const TSymbolUniqueId pt0e                             = TSymbolUniqueId(876);
+    static constexpr const TSymbolUniqueId imageSize_Image3D1               = TSymbolUniqueId(877);
+    static constexpr const TSymbolUniqueId pt0f                             = TSymbolUniqueId(878);
+    static constexpr const TSymbolUniqueId imageSize_IImage3D1              = TSymbolUniqueId(879);
+    static constexpr const TSymbolUniqueId pt0g                             = TSymbolUniqueId(880);
+    static constexpr const TSymbolUniqueId imageSize_UImage3D1              = TSymbolUniqueId(881);
+    static constexpr const TSymbolUniqueId pt0h                             = TSymbolUniqueId(882);
+    static constexpr const TSymbolUniqueId imageSize_Image2DArray1          = TSymbolUniqueId(883);
+    static constexpr const TSymbolUniqueId pt0i                             = TSymbolUniqueId(884);
+    static constexpr const TSymbolUniqueId imageSize_IImage2DArray1         = TSymbolUniqueId(885);
+    static constexpr const TSymbolUniqueId pt0j                             = TSymbolUniqueId(886);
+    static constexpr const TSymbolUniqueId imageSize_UImage2DArray1         = TSymbolUniqueId(887);
+    static constexpr const TSymbolUniqueId pt0k                             = TSymbolUniqueId(888);
+    static constexpr const TSymbolUniqueId imageSize_ImageCube1             = TSymbolUniqueId(889);
+    static constexpr const TSymbolUniqueId pt0l                             = TSymbolUniqueId(890);
+    static constexpr const TSymbolUniqueId imageSize_IImageCube1            = TSymbolUniqueId(891);
+    static constexpr const TSymbolUniqueId pt0m                             = TSymbolUniqueId(892);
+    static constexpr const TSymbolUniqueId imageSize_UImageCube1            = TSymbolUniqueId(893);
+    static constexpr const TSymbolUniqueId pt0n                             = TSymbolUniqueId(894);
+    static constexpr const TSymbolUniqueId imageLoad_Image2D1_Int2          = TSymbolUniqueId(895);
+    static constexpr const TSymbolUniqueId imageLoad_IImage2D1_Int2         = TSymbolUniqueId(896);
+    static constexpr const TSymbolUniqueId imageLoad_UImage2D1_Int2         = TSymbolUniqueId(897);
+    static constexpr const TSymbolUniqueId imageLoad_Image3D1_Int3          = TSymbolUniqueId(898);
+    static constexpr const TSymbolUniqueId imageLoad_IImage3D1_Int3         = TSymbolUniqueId(899);
+    static constexpr const TSymbolUniqueId imageLoad_UImage3D1_Int3         = TSymbolUniqueId(900);
+    static constexpr const TSymbolUniqueId imageLoad_Image2DArray1_Int3     = TSymbolUniqueId(901);
+    static constexpr const TSymbolUniqueId imageLoad_IImage2DArray1_Int3    = TSymbolUniqueId(902);
+    static constexpr const TSymbolUniqueId imageLoad_UImage2DArray1_Int3    = TSymbolUniqueId(903);
+    static constexpr const TSymbolUniqueId imageLoad_ImageCube1_Int3        = TSymbolUniqueId(904);
+    static constexpr const TSymbolUniqueId imageLoad_IImageCube1_Int3       = TSymbolUniqueId(905);
+    static constexpr const TSymbolUniqueId imageLoad_UImageCube1_Int3       = TSymbolUniqueId(906);
+    static constexpr const TSymbolUniqueId imageStore_Image2D1_Int2_Float4  = TSymbolUniqueId(907);
+    static constexpr const TSymbolUniqueId imageStore_IImage2D1_Int2_Int4   = TSymbolUniqueId(908);
+    static constexpr const TSymbolUniqueId imageStore_UImage2D1_Int2_UInt4  = TSymbolUniqueId(909);
+    static constexpr const TSymbolUniqueId imageStore_Image3D1_Int3_Float4  = TSymbolUniqueId(910);
+    static constexpr const TSymbolUniqueId imageStore_IImage3D1_Int3_Int4   = TSymbolUniqueId(911);
+    static constexpr const TSymbolUniqueId imageStore_UImage3D1_Int3_UInt4  = TSymbolUniqueId(912);
+    static constexpr const TSymbolUniqueId imageStore_Image2DArray1_Int3_Float4 =
+        TSymbolUniqueId(913);
+    static constexpr const TSymbolUniqueId imageStore_IImage2DArray1_Int3_Int4 =
+        TSymbolUniqueId(914);
+    static constexpr const TSymbolUniqueId imageStore_UImage2DArray1_Int3_UInt4 =
+        TSymbolUniqueId(915);
+    static constexpr const TSymbolUniqueId imageStore_ImageCube1_Int3_Float4 = TSymbolUniqueId(916);
+    static constexpr const TSymbolUniqueId imageStore_IImageCube1_Int3_Int4  = TSymbolUniqueId(917);
+    static constexpr const TSymbolUniqueId imageStore_UImageCube1_Int3_UInt4 = TSymbolUniqueId(918);
+    static constexpr const TSymbolUniqueId memoryBarrier                     = TSymbolUniqueId(919);
+    static constexpr const TSymbolUniqueId memoryBarrierAtomicCounter        = TSymbolUniqueId(920);
+    static constexpr const TSymbolUniqueId memoryBarrierBuffer               = TSymbolUniqueId(921);
+    static constexpr const TSymbolUniqueId memoryBarrierImage                = TSymbolUniqueId(922);
+    static constexpr const TSymbolUniqueId barrier                           = TSymbolUniqueId(923);
+    static constexpr const TSymbolUniqueId memoryBarrierShared               = TSymbolUniqueId(924);
+    static constexpr const TSymbolUniqueId groupMemoryBarrier                = TSymbolUniqueId(925);
+    static constexpr const TSymbolUniqueId EmitVertex                        = TSymbolUniqueId(926);
+    static constexpr const TSymbolUniqueId EndPrimitive                      = TSymbolUniqueId(927);
+    static constexpr const TSymbolUniqueId gl_DepthRangeParameters           = TSymbolUniqueId(928);
+    static constexpr const TSymbolUniqueId gl_DepthRange                     = TSymbolUniqueId(929);
+    static constexpr const TSymbolUniqueId gl_MaxVertexAttribs               = TSymbolUniqueId(930);
+    static constexpr const TSymbolUniqueId gl_MaxVertexUniformVectors        = TSymbolUniqueId(931);
+    static constexpr const TSymbolUniqueId gl_MaxVertexTextureImageUnits     = TSymbolUniqueId(932);
+    static constexpr const TSymbolUniqueId gl_MaxCombinedTextureImageUnits   = TSymbolUniqueId(933);
+    static constexpr const TSymbolUniqueId gl_MaxTextureImageUnits           = TSymbolUniqueId(934);
+    static constexpr const TSymbolUniqueId gl_MaxFragmentUniformVectors      = TSymbolUniqueId(935);
+    static constexpr const TSymbolUniqueId gl_MaxVaryingVectors              = TSymbolUniqueId(936);
+    static constexpr const TSymbolUniqueId gl_MaxDrawBuffers                 = TSymbolUniqueId(937);
+    static constexpr const TSymbolUniqueId gl_MaxDualSourceDrawBuffersEXT    = TSymbolUniqueId(938);
+    static constexpr const TSymbolUniqueId gl_MaxVertexOutputVectors         = TSymbolUniqueId(939);
+    static constexpr const TSymbolUniqueId gl_MaxFragmentInputVectors        = TSymbolUniqueId(940);
+    static constexpr const TSymbolUniqueId gl_MinProgramTexelOffset          = TSymbolUniqueId(941);
+    static constexpr const TSymbolUniqueId gl_MaxProgramTexelOffset          = TSymbolUniqueId(942);
+    static constexpr const TSymbolUniqueId gl_MaxImageUnits                  = TSymbolUniqueId(943);
+    static constexpr const TSymbolUniqueId gl_MaxVertexImageUniforms         = TSymbolUniqueId(944);
+    static constexpr const TSymbolUniqueId gl_MaxFragmentImageUniforms       = TSymbolUniqueId(945);
+    static constexpr const TSymbolUniqueId gl_MaxComputeImageUniforms        = TSymbolUniqueId(946);
+    static constexpr const TSymbolUniqueId gl_MaxCombinedImageUniforms       = TSymbolUniqueId(947);
+    static constexpr const TSymbolUniqueId gl_MaxCombinedShaderOutputResources =
+        TSymbolUniqueId(948);
+    static constexpr const TSymbolUniqueId gl_MaxComputeWorkGroupCount       = TSymbolUniqueId(949);
+    static constexpr const TSymbolUniqueId gl_MaxComputeWorkGroupSize        = TSymbolUniqueId(950);
+    static constexpr const TSymbolUniqueId gl_MaxComputeUniformComponents    = TSymbolUniqueId(951);
+    static constexpr const TSymbolUniqueId gl_MaxComputeTextureImageUnits    = TSymbolUniqueId(952);
+    static constexpr const TSymbolUniqueId gl_MaxComputeAtomicCounters       = TSymbolUniqueId(953);
+    static constexpr const TSymbolUniqueId gl_MaxComputeAtomicCounterBuffers = TSymbolUniqueId(954);
+    static constexpr const TSymbolUniqueId gl_MaxVertexAtomicCounters        = TSymbolUniqueId(955);
+    static constexpr const TSymbolUniqueId gl_MaxFragmentAtomicCounters      = TSymbolUniqueId(956);
+    static constexpr const TSymbolUniqueId gl_MaxCombinedAtomicCounters      = TSymbolUniqueId(957);
+    static constexpr const TSymbolUniqueId gl_MaxAtomicCounterBindings       = TSymbolUniqueId(958);
+    static constexpr const TSymbolUniqueId gl_MaxVertexAtomicCounterBuffers  = TSymbolUniqueId(959);
+    static constexpr const TSymbolUniqueId gl_MaxFragmentAtomicCounterBuffers =
+        TSymbolUniqueId(960);
+    static constexpr const TSymbolUniqueId gl_MaxCombinedAtomicCounterBuffers =
+        TSymbolUniqueId(961);
+    static constexpr const TSymbolUniqueId gl_MaxAtomicCounterBufferSize   = TSymbolUniqueId(962);
+    static constexpr const TSymbolUniqueId gl_MaxGeometryInputComponents   = TSymbolUniqueId(963);
+    static constexpr const TSymbolUniqueId gl_MaxGeometryOutputComponents  = TSymbolUniqueId(964);
+    static constexpr const TSymbolUniqueId gl_MaxGeometryImageUniforms     = TSymbolUniqueId(965);
+    static constexpr const TSymbolUniqueId gl_MaxGeometryTextureImageUnits = TSymbolUniqueId(966);
+    static constexpr const TSymbolUniqueId gl_MaxGeometryOutputVertices    = TSymbolUniqueId(967);
+    static constexpr const TSymbolUniqueId gl_MaxGeometryTotalOutputComponents =
+        TSymbolUniqueId(968);
+    static constexpr const TSymbolUniqueId gl_MaxGeometryUniformComponents = TSymbolUniqueId(969);
+    static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCounters    = TSymbolUniqueId(970);
+    static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCounterBuffers =
+        TSymbolUniqueId(971);
+    static constexpr const TSymbolUniqueId gl_FragCoord             = TSymbolUniqueId(972);
+    static constexpr const TSymbolUniqueId gl_FrontFacing           = TSymbolUniqueId(973);
+    static constexpr const TSymbolUniqueId gl_PointCoord            = TSymbolUniqueId(974);
+    static constexpr const TSymbolUniqueId gl_FragColor             = TSymbolUniqueId(975);
+    static constexpr const TSymbolUniqueId gl_FragData              = TSymbolUniqueId(976);
+    static constexpr const TSymbolUniqueId gl_FragDepth             = TSymbolUniqueId(977);
+    static constexpr const TSymbolUniqueId gl_SecondaryFragColorEXT = TSymbolUniqueId(978);
+    static constexpr const TSymbolUniqueId gl_SecondaryFragDataEXT  = TSymbolUniqueId(979);
+    static constexpr const TSymbolUniqueId gl_FragDepthEXT          = TSymbolUniqueId(980);
+    static constexpr const TSymbolUniqueId gl_LastFragData          = TSymbolUniqueId(981);
+    static constexpr const TSymbolUniqueId gl_LastFragColor         = TSymbolUniqueId(982);
+    static constexpr const TSymbolUniqueId gl_LastFragDataNV        = TSymbolUniqueId(983);
+    static constexpr const TSymbolUniqueId gl_LastFragColorARM      = TSymbolUniqueId(984);
+    static constexpr const TSymbolUniqueId gl_PrimitiveID           = TSymbolUniqueId(985);
+    static constexpr const TSymbolUniqueId gl_Layer                 = TSymbolUniqueId(986);
+    static constexpr const TSymbolUniqueId gl_Position              = TSymbolUniqueId(987);
+    static constexpr const TSymbolUniqueId gl_PointSize             = TSymbolUniqueId(988);
+    static constexpr const TSymbolUniqueId gl_InstanceID            = TSymbolUniqueId(989);
+    static constexpr const TSymbolUniqueId gl_VertexID              = TSymbolUniqueId(990);
+    static constexpr const TSymbolUniqueId gl_ViewportIndex         = TSymbolUniqueId(991);
+    static constexpr const TSymbolUniqueId gl_LayerVS               = TSymbolUniqueId(992);
+    static constexpr const TSymbolUniqueId gl_NumWorkGroups         = TSymbolUniqueId(993);
+    static constexpr const TSymbolUniqueId gl_WorkGroupSize         = TSymbolUniqueId(994);
+    static constexpr const TSymbolUniqueId gl_WorkGroupID           = TSymbolUniqueId(995);
+    static constexpr const TSymbolUniqueId gl_LocalInvocationID     = TSymbolUniqueId(996);
+    static constexpr const TSymbolUniqueId gl_GlobalInvocationID    = TSymbolUniqueId(997);
+    static constexpr const TSymbolUniqueId gl_LocalInvocationIndex  = TSymbolUniqueId(998);
+    static constexpr const TSymbolUniqueId gl_PrimitiveIDIn         = TSymbolUniqueId(999);
+    static constexpr const TSymbolUniqueId gl_InvocationID          = TSymbolUniqueId(1000);
+    static constexpr const TSymbolUniqueId gl_PrimitiveIDGS         = TSymbolUniqueId(1001);
+    static constexpr const TSymbolUniqueId gl_LayerGS               = TSymbolUniqueId(1002);
+    static constexpr const TSymbolUniqueId gl_PerVertex             = TSymbolUniqueId(1003);
+    static constexpr const TSymbolUniqueId gl_in                    = TSymbolUniqueId(1004);
+    static constexpr const TSymbolUniqueId gl_PerVertexOutBlock     = TSymbolUniqueId(1005);
+    static constexpr const TSymbolUniqueId gl_PositionGS            = TSymbolUniqueId(1006);
+    static constexpr const TSymbolUniqueId gl_ViewID_OVR            = TSymbolUniqueId(1007);
+    static constexpr const TSymbolUniqueId gl_ViewID_OVRESSL1       = TSymbolUniqueId(1008);
+
+};  // class BuiltInId
+
+namespace BuiltInVariable
+{
+
+const TVariable *gl_FragColor();
+const TVariable *gl_FragCoord();
+const TVariable *gl_FragDepth();
+const TVariable *gl_FrontFacing();
+const TVariable *gl_GlobalInvocationID();
+const TVariable *gl_InstanceID();
+const TVariable *gl_InvocationID();
+const TVariable *gl_LastFragColor();
+const TVariable *gl_LastFragColorARM();
+const TVariable *gl_Layer();
+const TVariable *gl_LayerGS();
+const TVariable *gl_LayerVS();
+const TVariable *gl_LocalInvocationID();
+const TVariable *gl_LocalInvocationIndex();
+const TVariable *gl_NumWorkGroups();
+const TVariable *gl_PointCoord();
+const TVariable *gl_PointSize();
+const TVariable *gl_Position();
+const TVariable *gl_PrimitiveID();
+const TVariable *gl_PrimitiveIDGS();
+const TVariable *gl_PrimitiveIDIn();
+const TVariable *gl_SecondaryFragColorEXT();
+const TVariable *gl_VertexID();
+const TVariable *gl_ViewID_OVR();
+const TVariable *gl_ViewID_OVRESSL1();
+const TVariable *gl_ViewportIndex();
+const TVariable *gl_WorkGroupID();
+const TVariable *gl_WorkGroupSize();
+
+}  // namespace BuiltInVariable
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.cpp
@@ -0,0 +1,39 @@
+//
+// Copyright (c) 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
+{
+
+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
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.h
@@ -0,0 +1,23 @@
+//
+// Copyright (c) 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_
+
+namespace sh
+{
+
+class TIntermBlock;
+class TIntermFunctionDefinition;
+
+TIntermFunctionDefinition *FindMain(TIntermBlock *root);
+TIntermBlock *FindMainBody(TIntermBlock *root);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEUTIL_FINDMAIN_H_
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.cpp
@@ -0,0 +1,54 @@
+//
+// Copyright (c) 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)
+    {
+        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
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.h
@@ -0,0 +1,23 @@
+//
+// Copyright (c) 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_
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.cpp
@@ -0,0 +1,199 @@
+//
+// Copyright (c) 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"
+
+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::IsDynamicIndexingOfVectorOrMatrix(TIntermBinary *node)
+{
+    return node->getOp() == EOpIndexIndirect && !node->getLeft()->isArray() &&
+           node->getLeft()->getBasicType() != EbtStruct;
+}
+
+bool IntermNodePatternMatcher::matchInternal(TIntermBinary *node, TIntermNode *parentNode)
+{
+    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)
+{
+    if ((mMask & kArrayLengthMethod) != 0)
+    {
+        if (node->getOp() == EOpArrayLength)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool IntermNodePatternMatcher::match(TIntermBinary *node, TIntermNode *parentNode)
+{
+    // 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)
+{
+    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)
+{
+    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()) && !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)
+{
+    if ((mMask & kUnfoldedShortCircuitExpression) != 0)
+    {
+        return true;
+    }
+    return false;
+}
+
+bool IntermNodePatternMatcher::match(TIntermDeclaration *node)
+{
+    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
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.h
@@ -0,0 +1,79 @@
+//
+// Copyright (c) 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 IsDynamicIndexingOfVectorOrMatrix(TIntermBinary *node);
+
+    enum PatternType
+    {
+        // Matches expressions that are unfolded to if statements by UnfoldShortCircuitToIf
+        kUnfoldedShortCircuitExpression = 0x0001,
+
+        // Matches expressions that return arrays with the exception of simple statements where a
+        // constructor or function call result is assigned.
+        kExpressionReturningArray = 0x0001 << 1,
+
+        // Matches dynamic indexing of vectors or matrices in l-values.
+        kDynamicIndexingOfVectorOrMatrixInLValue = 0x0001 << 2,
+
+        // Matches declarations with more than one declared variables.
+        kMultiDeclaration = 0x0001 << 3,
+
+        // Matches declarations of arrays.
+        kArrayDeclaration = 0x0001 << 4,
+
+        // Matches declarations of structs where the struct type does not have a name.
+        kNamelessStructDeclaration = 0x0001 << 5,
+
+        // Matches array length() method.
+        kArrayLengthMethod = 0x0001 << 6,
+
+        // Matches a vector or matrix constructor whose arguments are scalarized by the
+        // SH_SCALARIZE_VEC_OR_MAT_CONSTRUCTOR_ARGUMENTS workaround.
+        kScalarizedVecOrMatConstructor = 0x0001 << 7
+    };
+    IntermNodePatternMatcher(const unsigned int mask);
+
+    bool match(TIntermUnary *node);
+
+    bool match(TIntermBinary *node, TIntermNode *parentNode);
+
+    // Use this version for checking binary node matches in case you're using flag
+    // kDynamicIndexingOfVectorOrMatrixInLValue.
+    bool match(TIntermBinary *node, TIntermNode *parentNode, bool isLValueRequiredHere);
+
+    bool match(TIntermAggregate *node, TIntermNode *parentNode);
+    bool match(TIntermTernary *node);
+    bool match(TIntermDeclaration *node);
+
+  private:
+    const unsigned int mMask;
+
+    bool matchInternal(TIntermBinary *node, TIntermNode *parentNode);
+};
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEUTIL_INTERMNODEPATTERNMATCHER_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.cpp
@@ -0,0 +1,269 @@
+//
+// Copyright (c) 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 typecheck.
+                    // 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;
+    }
+
+    if (type.getBasicType() == EbtVoid)
+    {
+        // Void array. This happens only on error condition, similarly to the case above. We don't
+        // have a constructor operator for void, so this needs special handling. We'll end up with a
+        // value without the array type, but that should not be a problem.
+        while (constType.isArray())
+        {
+            constType.toArrayElementType();
+        }
+        return CreateZeroNode(constType);
+    }
+
+    TIntermSequence *arguments = new TIntermSequence();
+
+    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 *CreateIndexNode(int index)
+{
+    TConstantUnion *u = new TConstantUnion[1];
+    u[0].setIConst(index);
+
+    TType type(EbtInt, EbpUndefined, EvqConst, 1);
+    TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
+    return node;
+}
+
+TIntermConstantUnion *CreateBoolNode(bool value)
+{
+    TConstantUnion *u = new TConstantUnion[1];
+    u[0].setBConst(value);
+
+    TType type(EbtBool, EbpUndefined, EvqConst, 1);
+    TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
+    return node;
+}
+
+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, ImmutableString(""), 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;
+}
+
+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 TVariable *var = reinterpret_cast<const TVariable *>(symbolTable.findGlobal(name));
+    ASSERT(var);
+    return new TIntermSymbol(var);
+}
+
+TIntermSymbol *ReferenceBuiltInVariable(const ImmutableString &name,
+                                        const TSymbolTable &symbolTable,
+                                        int shaderVersion)
+{
+    const TVariable *var =
+        reinterpret_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 (op != EOpCallBuiltInFunction && arguments->size() == 1)
+    {
+        return new TIntermUnary(op, arguments->at(0)->getAsTyped(), fn);
+    }
+    return TIntermAggregate::CreateBuiltInFunctionCall(*fn, arguments);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.h
@@ -0,0 +1,68 @@
+//
+// Copyright (c) 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"
+
+namespace sh
+{
+
+class TSymbolTable;
+class TVariable;
+
+TIntermFunctionPrototype *CreateInternalFunctionPrototypeNode(const TFunction &func);
+TIntermFunctionDefinition *CreateInternalFunctionDefinitionNode(const TFunction &func,
+                                                                TIntermBlock *functionBody);
+
+TIntermTyped *CreateZeroNode(const TType &type);
+TIntermConstantUnion *CreateIndexNode(int index);
+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);
+
+// 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_autogen.h.
+TIntermSymbol *ReferenceBuiltInVariable(const ImmutableString &name,
+                                        const TSymbolTable &symbolTable,
+                                        int shaderVersion);
+
+TIntermTyped *CreateBuiltInFunctionCallNode(const char *name,
+                                            TIntermSequence *arguments,
+                                            const TSymbolTable &symbolTable,
+                                            int shaderVersion);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_INTERMNODEUTIL_H_
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.cpp
@@ -0,0 +1,870 @@
+//
+// Copyright (c) 2002-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/tree_util/IntermTraverse.h"
+
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+
+namespace sh
+{
+
+void TIntermSymbol::traverse(TIntermTraverser *it)
+{
+    it->traverseSymbol(this);
+}
+
+void TIntermRaw::traverse(TIntermTraverser *it)
+{
+    it->traverseRaw(this);
+}
+
+void TIntermConstantUnion::traverse(TIntermTraverser *it)
+{
+    it->traverseConstantUnion(this);
+}
+
+void TIntermSwizzle::traverse(TIntermTraverser *it)
+{
+    it->traverseSwizzle(this);
+}
+
+void TIntermBinary::traverse(TIntermTraverser *it)
+{
+    it->traverseBinary(this);
+}
+
+void TIntermUnary::traverse(TIntermTraverser *it)
+{
+    it->traverseUnary(this);
+}
+
+void TIntermTernary::traverse(TIntermTraverser *it)
+{
+    it->traverseTernary(this);
+}
+
+void TIntermIfElse::traverse(TIntermTraverser *it)
+{
+    it->traverseIfElse(this);
+}
+
+void TIntermSwitch::traverse(TIntermTraverser *it)
+{
+    it->traverseSwitch(this);
+}
+
+void TIntermCase::traverse(TIntermTraverser *it)
+{
+    it->traverseCase(this);
+}
+
+void TIntermFunctionDefinition::traverse(TIntermTraverser *it)
+{
+    it->traverseFunctionDefinition(this);
+}
+
+void TIntermBlock::traverse(TIntermTraverser *it)
+{
+    it->traverseBlock(this);
+}
+
+void TIntermInvariantDeclaration::traverse(TIntermTraverser *it)
+{
+    it->traverseInvariantDeclaration(this);
+}
+
+void TIntermDeclaration::traverse(TIntermTraverser *it)
+{
+    it->traverseDeclaration(this);
+}
+
+void TIntermFunctionPrototype::traverse(TIntermTraverser *it)
+{
+    it->traverseFunctionPrototype(this);
+}
+
+void TIntermAggregate::traverse(TIntermTraverser *it)
+{
+    it->traverseAggregate(this);
+}
+
+void TIntermLoop::traverse(TIntermTraverser *it)
+{
+    it->traverseLoop(this);
+}
+
+void TIntermBranch::traverse(TIntermTraverser *it)
+{
+    it->traverseBranch(this);
+}
+
+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)
+{
+}
+
+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 TLValueTrackingTraverser::setInFunctionCallOutParameter(bool inOutParameter)
+{
+    mInFunctionCallOutParameter = inOutParameter;
+}
+
+bool TLValueTrackingTraverser::isInFunctionCallOutParameter() const
+{
+    return mInFunctionCallOutParameter;
+}
+
+//
+// Traverse the intermediate representation tree, and
+// call a node type specific function for each node.
+// Done recursively through the member function Traverse().
+// Node types can be skipped if their function to call is 0,
+// but their subtree will still be traversed.
+// Nodes with children can have their whole subtree skipped
+// if preVisit is turned on and the type specific function
+// returns false.
+//
+
+//
+// Traversal functions for terminals are straighforward....
+//
+void TIntermTraverser::traverseSymbol(TIntermSymbol *node)
+{
+    ScopedNodeInTraversalPath addToPath(this, node);
+    visitSymbol(node);
+}
+
+void TIntermTraverser::traverseConstantUnion(TIntermConstantUnion *node)
+{
+    ScopedNodeInTraversalPath addToPath(this, node);
+    visitConstantUnion(node);
+}
+
+void TIntermTraverser::traverseSwizzle(TIntermSwizzle *node)
+{
+    ScopedNodeInTraversalPath addToPath(this, node);
+    if (!addToPath.isWithinDepthLimit())
+        return;
+
+    bool visit = true;
+
+    if (preVisit)
+        visit = visitSwizzle(PreVisit, node);
+
+    if (visit)
+    {
+        node->getOperand()->traverse(this);
+    }
+
+    if (visit && postVisit)
+        visitSwizzle(PostVisit, node);
+}
+
+//
+// Traverse a binary node.
+//
+void TIntermTraverser::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 = visitBinary(PreVisit, node);
+
+    //
+    // Visit the children, in the right order.
+    //
+    if (visit)
+    {
+        if (node->getLeft())
+            node->getLeft()->traverse(this);
+
+        if (inVisit)
+            visit = visitBinary(InVisit, node);
+
+        if (visit && node->getRight())
+            node->getRight()->traverse(this);
+    }
+
+    //
+    // Visit the node after the children, if requested and the traversal
+    // hasn't been cancelled yet.
+    //
+    if (visit && postVisit)
+        visitBinary(PostVisit, 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 = visitBinary(PreVisit, node);
+
+    //
+    // Visit the children, in the right order.
+    //
+    if (visit)
+    {
+        // Some binary operations like indexing can be inside an expression which must be an
+        // l-value.
+        bool parentOperatorRequiresLValue     = operatorRequiresLValue();
+        bool parentInFunctionCallOutParameter = isInFunctionCallOutParameter();
+        if (node->isAssignment())
+        {
+            ASSERT(!isLValueRequiredHere());
+            setOperatorRequiresLValue(true);
+        }
+
+        if (node->getLeft())
+            node->getLeft()->traverse(this);
+
+        if (inVisit)
+            visit = visitBinary(InVisit, node);
+
+        if (node->isAssignment())
+            setOperatorRequiresLValue(false);
+
+        // 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);
+        }
+
+        if (visit && node->getRight())
+            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 (visit && postVisit)
+        visitBinary(PostVisit, node);
+}
+
+//
+// Traverse a unary node.  Same comments in binary node apply here.
+//
+void TIntermTraverser::traverseUnary(TIntermUnary *node)
+{
+    ScopedNodeInTraversalPath addToPath(this, node);
+    if (!addToPath.isWithinDepthLimit())
+        return;
+
+    bool visit = true;
+
+    if (preVisit)
+        visit = visitUnary(PreVisit, node);
+
+    if (visit)
+    {
+        node->getOperand()->traverse(this);
+    }
+
+    if (visit && postVisit)
+        visitUnary(PostVisit, node);
+}
+
+void TLValueTrackingTraverser::traverseUnary(TIntermUnary *node)
+{
+    ScopedNodeInTraversalPath addToPath(this, node);
+    if (!addToPath.isWithinDepthLimit())
+        return;
+
+    bool visit = true;
+
+    if (preVisit)
+        visit = visitUnary(PreVisit, node);
+
+    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 (visit && postVisit)
+        visitUnary(PostVisit, node);
+}
+
+// Traverse a function definition node.
+void TIntermTraverser::traverseFunctionDefinition(TIntermFunctionDefinition *node)
+{
+    ScopedNodeInTraversalPath addToPath(this, node);
+    if (!addToPath.isWithinDepthLimit())
+        return;
+
+    bool visit = true;
+
+    if (preVisit)
+        visit = visitFunctionDefinition(PreVisit, node);
+
+    if (visit)
+    {
+        mInGlobalScope = false;
+
+        node->getFunctionPrototype()->traverse(this);
+        if (inVisit)
+            visit = visitFunctionDefinition(InVisit, node);
+        node->getBody()->traverse(this);
+
+        mInGlobalScope = true;
+    }
+
+    if (visit && postVisit)
+        visitFunctionDefinition(PostVisit, node);
+}
+
+// Traverse a block node.
+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 = visitBlock(PreVisit, node);
+
+    if (visit)
+    {
+        for (auto *child : *sequence)
+        {
+            child->traverse(this);
+            if (visit && inVisit)
+            {
+                if (child != sequence->back())
+                    visit = visitBlock(InVisit, node);
+            }
+
+            incrementParentBlockPos();
+        }
+    }
+
+    if (visit && postVisit)
+        visitBlock(PostVisit, node);
+
+    popParentBlock();
+}
+
+void TIntermTraverser::traverseInvariantDeclaration(TIntermInvariantDeclaration *node)
+{
+    ScopedNodeInTraversalPath addToPath(this, node);
+    if (!addToPath.isWithinDepthLimit())
+        return;
+
+    bool visit = true;
+
+    if (preVisit)
+    {
+        visit = visitInvariantDeclaration(PreVisit, node);
+    }
+
+    if (visit)
+    {
+        node->getSymbol()->traverse(this);
+        if (postVisit)
+        {
+            visitInvariantDeclaration(PostVisit, node);
+        }
+    }
+}
+
+// Traverse a declaration node.
+void TIntermTraverser::traverseDeclaration(TIntermDeclaration *node)
+{
+    ScopedNodeInTraversalPath addToPath(this, node);
+    if (!addToPath.isWithinDepthLimit())
+        return;
+
+    bool visit = true;
+
+    TIntermSequence *sequence = node->getSequence();
+
+    if (preVisit)
+        visit = visitDeclaration(PreVisit, node);
+
+    if (visit)
+    {
+        for (auto *child : *sequence)
+        {
+            child->traverse(this);
+            if (visit && inVisit)
+            {
+                if (child != sequence->back())
+                    visit = visitDeclaration(InVisit, node);
+            }
+        }
+    }
+
+    if (visit && postVisit)
+        visitDeclaration(PostVisit, node);
+}
+
+void TIntermTraverser::traverseFunctionPrototype(TIntermFunctionPrototype *node)
+{
+    ScopedNodeInTraversalPath addToPath(this, node);
+
+    visitFunctionPrototype(node);
+}
+
+// Traverse an aggregate node.  Same comments in binary node apply here.
+void TIntermTraverser::traverseAggregate(TIntermAggregate *node)
+{
+    ScopedNodeInTraversalPath addToPath(this, node);
+    if (!addToPath.isWithinDepthLimit())
+        return;
+
+    bool visit = true;
+
+    TIntermSequence *sequence = node->getSequence();
+
+    if (preVisit)
+        visit = visitAggregate(PreVisit, node);
+
+    if (visit)
+    {
+        for (auto *child : *sequence)
+        {
+            child->traverse(this);
+            if (visit && inVisit)
+            {
+                if (child != sequence->back())
+                    visit = visitAggregate(InVisit, node);
+            }
+        }
+    }
+
+    if (visit && postVisit)
+        visitAggregate(PostVisit, 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;
+}
+
+void TIntermTraverser::updateTree()
+{
+    // Sort the insertions so that insertion position is decreasing. This way multiple insertions to
+    // the same parent node are handled correctly.
+    std::sort(mInsertions.begin(), mInsertions.end(), CompareInsertion);
+    for (size_t ii = 0; ii < mInsertions.size(); ++ii)
+    {
+        // We can't know here what the intended ordering of two insertions to the same position is,
+        // so it is not supported.
+        ASSERT(ii == 0 || mInsertions[ii].position != mInsertions[ii - 1].position ||
+               mInsertions[ii].parent != mInsertions[ii - 1].parent);
+        const NodeInsertMultipleEntry &insertion = mInsertions[ii];
+        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);
+
+        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();
+}
+
+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));
+}
+
+TLValueTrackingTraverser::TLValueTrackingTraverser(bool preVisit,
+                                                   bool inVisit,
+                                                   bool postVisit,
+                                                   TSymbolTable *symbolTable)
+    : TIntermTraverser(preVisit, inVisit, postVisit, 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 = visitAggregate(PreVisit, node);
+
+    if (visit)
+    {
+        size_t paramIndex = 0u;
+        for (auto *child : *sequence)
+        {
+            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 == EvqOut || qualifier == EvqInOut);
+                ++paramIndex;
+            }
+            else
+            {
+                ASSERT(node->isConstructor());
+            }
+
+            child->traverse(this);
+            if (visit && inVisit)
+            {
+                if (child != sequence->back())
+                    visit = visitAggregate(InVisit, node);
+            }
+        }
+        setInFunctionCallOutParameter(false);
+    }
+
+    if (visit && postVisit)
+        visitAggregate(PostVisit, node);
+}
+
+//
+// Traverse a ternary node.  Same comments in binary node apply here.
+//
+void TIntermTraverser::traverseTernary(TIntermTernary *node)
+{
+    ScopedNodeInTraversalPath addToPath(this, node);
+    if (!addToPath.isWithinDepthLimit())
+        return;
+
+    bool visit = true;
+
+    if (preVisit)
+        visit = visitTernary(PreVisit, node);
+
+    if (visit)
+    {
+        node->getCondition()->traverse(this);
+        if (node->getTrueExpression())
+            node->getTrueExpression()->traverse(this);
+        if (node->getFalseExpression())
+            node->getFalseExpression()->traverse(this);
+    }
+
+    if (visit && postVisit)
+        visitTernary(PostVisit, node);
+}
+
+// Traverse an if-else node.  Same comments in binary node apply here.
+void TIntermTraverser::traverseIfElse(TIntermIfElse *node)
+{
+    ScopedNodeInTraversalPath addToPath(this, node);
+    if (!addToPath.isWithinDepthLimit())
+        return;
+
+    bool visit = true;
+
+    if (preVisit)
+        visit = visitIfElse(PreVisit, node);
+
+    if (visit)
+    {
+        node->getCondition()->traverse(this);
+        if (node->getTrueBlock())
+            node->getTrueBlock()->traverse(this);
+        if (node->getFalseBlock())
+            node->getFalseBlock()->traverse(this);
+    }
+
+    if (visit && postVisit)
+        visitIfElse(PostVisit, node);
+}
+
+//
+// Traverse a switch node.  Same comments in binary node apply here.
+//
+void TIntermTraverser::traverseSwitch(TIntermSwitch *node)
+{
+    ScopedNodeInTraversalPath addToPath(this, node);
+    if (!addToPath.isWithinDepthLimit())
+        return;
+
+    bool visit = true;
+
+    if (preVisit)
+        visit = visitSwitch(PreVisit, node);
+
+    if (visit)
+    {
+        node->getInit()->traverse(this);
+        if (inVisit)
+            visit = visitSwitch(InVisit, node);
+        if (visit && node->getStatementList())
+            node->getStatementList()->traverse(this);
+    }
+
+    if (visit && postVisit)
+        visitSwitch(PostVisit, node);
+}
+
+//
+// Traverse a case node.  Same comments in binary node apply here.
+//
+void TIntermTraverser::traverseCase(TIntermCase *node)
+{
+    ScopedNodeInTraversalPath addToPath(this, node);
+    if (!addToPath.isWithinDepthLimit())
+        return;
+
+    bool visit = true;
+
+    if (preVisit)
+        visit = visitCase(PreVisit, node);
+
+    if (visit && node->getCondition())
+    {
+        node->getCondition()->traverse(this);
+    }
+
+    if (visit && postVisit)
+        visitCase(PostVisit, node);
+}
+
+//
+// Traverse a loop node.  Same comments in binary node apply here.
+//
+void TIntermTraverser::traverseLoop(TIntermLoop *node)
+{
+    ScopedNodeInTraversalPath addToPath(this, node);
+    if (!addToPath.isWithinDepthLimit())
+        return;
+
+    bool visit = true;
+
+    if (preVisit)
+        visit = visitLoop(PreVisit, node);
+
+    if (visit)
+    {
+        if (node->getInit())
+            node->getInit()->traverse(this);
+
+        if (node->getCondition())
+            node->getCondition()->traverse(this);
+
+        if (node->getBody())
+            node->getBody()->traverse(this);
+
+        if (node->getExpression())
+            node->getExpression()->traverse(this);
+    }
+
+    if (visit && postVisit)
+        visitLoop(PostVisit, node);
+}
+
+//
+// Traverse a branch node.  Same comments in binary node apply here.
+//
+void TIntermTraverser::traverseBranch(TIntermBranch *node)
+{
+    ScopedNodeInTraversalPath addToPath(this, node);
+    if (!addToPath.isWithinDepthLimit())
+        return;
+
+    bool visit = true;
+
+    if (preVisit)
+        visit = visitBranch(PreVisit, node);
+
+    if (visit && node->getExpression())
+    {
+        node->getExpression()->traverse(this);
+    }
+
+    if (visit && postVisit)
+        visitBranch(PostVisit, node);
+}
+
+void TIntermTraverser::traverseRaw(TIntermRaw *node)
+{
+    ScopedNodeInTraversalPath addToPath(this, node);
+    visitRaw(node);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.h
@@ -0,0 +1,323 @@
+//
+// Copyright (c) 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"
+
+namespace sh
+{
+
+class TSymbolTable;
+class TSymbolUniqueId;
+
+enum Visit
+{
+    PreVisit,
+    InVisit,
+    PostVisit
+};
+
+// 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.
+class TIntermTraverser : angle::NonCopyable
+{
+  public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    TIntermTraverser(bool preVisit,
+                     bool inVisit,
+                     bool postVisit,
+                     TSymbolTable *symbolTable = nullptr);
+    virtual ~TIntermTraverser();
+
+    virtual void visitSymbol(TIntermSymbol *node) {}
+    virtual void visitRaw(TIntermRaw *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 visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *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; }
+
+    // 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.
+    virtual void traverseSymbol(TIntermSymbol *node);
+    virtual void traverseRaw(TIntermRaw *node);
+    virtual void traverseConstantUnion(TIntermConstantUnion *node);
+    virtual void traverseSwizzle(TIntermSwizzle *node);
+    virtual void traverseBinary(TIntermBinary *node);
+    virtual void traverseUnary(TIntermUnary *node);
+    virtual void traverseTernary(TIntermTernary *node);
+    virtual void traverseIfElse(TIntermIfElse *node);
+    virtual void traverseSwitch(TIntermSwitch *node);
+    virtual void traverseCase(TIntermCase *node);
+    virtual void traverseFunctionPrototype(TIntermFunctionPrototype *node);
+    virtual void traverseFunctionDefinition(TIntermFunctionDefinition *node);
+    virtual void traverseAggregate(TIntermAggregate *node);
+    virtual void traverseBlock(TIntermBlock *node);
+    virtual void traverseInvariantDeclaration(TIntermInvariantDeclaration *node);
+    virtual void traverseDeclaration(TIntermDeclaration *node);
+    virtual void traverseLoop(TIntermLoop *node);
+    virtual void traverseBranch(TIntermBranch *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.
+    void updateTree();
+
+  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; }
+
+    // RAII helper for incrementDepth/decrementDepth
+    class 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;
+    };
+
+    TIntermNode *getParentNode() { 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)
+    {
+        if (mPath.size() > n + 1u)
+        {
+            return mPath[mPath.size() - n - 2u];
+        }
+        return nullptr;
+    }
+
+    const TIntermBlock *getParentBlock() const;
+
+    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 *_parent,
+                                     TIntermNode *_original,
+                                     TIntermSequence _replacements)
+            : parent(_parent), original(_original), replacements(_replacements)
+        {
+        }
+
+        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);
+
+    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);
+
+    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;
+
+    // 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);
+    virtual ~TLValueTrackingTraverser() {}
+
+    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_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/NodeSearch.h
@@ -0,0 +1,56 @@
+//
+// Copyright (c) 2002-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.
+//
+// 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:
+    virtual bool visitBranch(Visit visit, TIntermBranch *node)
+    {
+        switch (node->getFlowOp())
+        {
+            case EOpKill:
+                mFound = true;
+                break;
+
+            default:
+                break;
+        }
+
+        return !mFound;
+    }
+};
+}
+
+#endif  // COMPILER_TRANSLATOR_TREEUTIL_NODESEARCH_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.cpp
@@ -0,0 +1,55 @@
+//
+// Copyright (c) 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/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class ReplaceVariableTraverser : public TIntermTraverser
+{
+  public:
+    ReplaceVariableTraverser(const TVariable *toBeReplaced, const TVariable *replacement)
+        : TIntermTraverser(true, false, false),
+          mToBeReplaced(toBeReplaced),
+          mReplacement(replacement)
+    {
+    }
+
+    void visitSymbol(TIntermSymbol *node) override
+    {
+        if (&node->variable() == mToBeReplaced)
+        {
+            queueReplacement(new TIntermSymbol(mReplacement), OriginalNode::IS_DROPPED);
+        }
+    }
+
+  private:
+    const TVariable *const mToBeReplaced;
+    const TVariable *const mReplacement;
+};
+
+}  // anonymous namespace
+
+// Replaces every occurrence of a variable with another variable.
+void ReplaceVariable(TIntermBlock *root,
+                     const TVariable *toBeReplaced,
+                     const TVariable *replacement)
+{
+    ReplaceVariableTraverser traverser(toBeReplaced, replacement);
+    root->traverse(&traverser);
+    traverser.updateTree();
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.h
@@ -0,0 +1,24 @@
+//
+// Copyright (c) 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_
+
+namespace sh
+{
+
+class TIntermBlock;
+class TVariable;
+
+void ReplaceVariable(TIntermBlock *root,
+                     const TVariable *toBeReplaced,
+                     const TVariable *replacement);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEUTIL_REPLACEVARIABLE_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.cpp
@@ -0,0 +1,115 @@
+//
+// Copyright (c) 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.
+//
+
+#include "compiler/translator/tree_util/RunAtTheEndOfShader.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 ContainsReturnTraverser : public TIntermTraverser
+{
+  public:
+    ContainsReturnTraverser() : TIntermTraverser(true, false, false), mContainsReturn(false) {}
+
+    bool visitBranch(Visit visit, TIntermBranch *node) override
+    {
+        if (node->getFlowOp() == EOpReturn)
+        {
+            mContainsReturn = true;
+        }
+        return false;
+    }
+
+    bool containsReturn() { return mContainsReturn; }
+
+  private:
+    bool mContainsReturn;
+};
+
+bool ContainsReturn(TIntermNode *node)
+{
+    ContainsReturnTraverser traverser;
+    node->traverse(&traverser);
+    return traverser.containsReturn();
+}
+
+void WrapMainAndAppend(TIntermBlock *root,
+                       TIntermFunctionDefinition *main,
+                       TIntermNode *codeToRun,
+                       TSymbolTable *symbolTable)
+{
+    // Replace main() with main0() with the same body.
+    TFunction *oldMain = new TFunction(symbolTable, ImmutableString(""), SymbolType::AngleInternal,
+                                       StaticType::GetBasic<EbtVoid>(), 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>(), false);
+    TIntermFunctionPrototype *newMainProto = new TIntermFunctionPrototype(newMain);
+
+    // {
+    //     main0();
+    //     codeToRun
+    // }
+    TIntermBlock *newMainBody = new TIntermBlock();
+    TIntermAggregate *oldMainCall =
+        TIntermAggregate::CreateFunctionCall(*oldMain, new TIntermSequence());
+    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
+
+void RunAtTheEndOfShader(TIntermBlock *root, TIntermNode *codeToRun, TSymbolTable *symbolTable)
+{
+    TIntermFunctionDefinition *main = FindMain(root);
+    if (!ContainsReturn(main))
+    {
+        main->getBody()->appendStatement(codeToRun);
+        return;
+    }
+
+    WrapMainAndAppend(root, main, codeToRun, symbolTable);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.h
@@ -0,0 +1,23 @@
+//
+// Copyright (c) 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_
+
+namespace sh
+{
+
+class TIntermBlock;
+class TIntermNode;
+class TSymbolTable;
+
+void RunAtTheEndOfShader(TIntermBlock *root, TIntermNode *codeToRun, TSymbolTable *symbolTable);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_TREEUTIL_RUNATTHEENDOFSHADER_H_
\ No newline at end of file
--- a/gfx/angle/checkout/src/libANGLE/BinaryStream.h
+++ b/gfx/angle/checkout/src/libANGLE/BinaryStream.h
@@ -51,16 +51,29 @@ class BinaryInputStream : angle::NonCopy
     {
         unsigned int size = readInt<unsigned int>();
         for (unsigned int index = 0; index < size; ++index)
         {
             param->push_back(readInt<IntT>());
         }
     }
 
+    template <class EnumT>
+    EnumT readEnum()
+    {
+        using UnderlyingType = typename std::underlying_type<EnumT>::type;
+        return static_cast<EnumT>(readInt<UnderlyingType>());
+    }
+
+    template <class EnumT>
+    void readEnum(EnumT *outValue)
+    {
+        *outValue = readEnum<EnumT>();
+    }
+
     bool readBool()
     {
         int value = 0;
         read(&value);
         return (value > 0);
     }
 
     void readBool(bool *outValue)
@@ -211,16 +224,23 @@ class BinaryOutputStream : angle::NonCop
     {
         writeInt(param.size());
         for (IntT element : param)
         {
             writeIntOrNegOne(element);
         }
     }
 
+    template <class EnumT>
+    void writeEnum(EnumT param)
+    {
+        using UnderlyingType = typename std::underlying_type<EnumT>::type;
+        writeInt<UnderlyingType>(static_cast<UnderlyingType>(param));
+    }
+
     void writeString(const std::string &v)
     {
         writeInt(v.length());
         write(v.c_str(), v.length());
     }
 
     void writeBytes(const unsigned char *bytes, size_t count)
     {
--- a/gfx/angle/checkout/src/libANGLE/Buffer.cpp
+++ b/gfx/angle/checkout/src/libANGLE/Buffer.cpp
@@ -21,17 +21,19 @@ BufferState::BufferState()
     : mLabel(),
       mUsage(BufferUsage::StaticDraw),
       mSize(0),
       mAccessFlags(0),
       mAccess(GL_WRITE_ONLY_OES),
       mMapped(GL_FALSE),
       mMapPointer(nullptr),
       mMapOffset(0),
-      mMapLength(0)
+      mMapLength(0),
+      mBindingCount(0),
+      mTransformFeedbackBindingCount(0)
 {
 }
 
 BufferState::~BufferState()
 {
 }
 
 Buffer::Buffer(rx::GLImplFactory *factory, GLuint id)
@@ -81,43 +83,52 @@ Error Buffer::bufferData(const Context *
     }
 
     ANGLE_TRY(mImpl->setData(context, target, dataForImpl, size, usage));
 
     mIndexRangeCache.clear();
     mState.mUsage = usage;
     mState.mSize  = size;
 
+    // Notify when data changes.
+    mImpl->onStateChange(context, angle::SubjectMessage::CONTENTS_CHANGED);
+
     return NoError();
 }
 
 Error Buffer::bufferSubData(const Context *context,
                             BufferBinding target,
                             const void *data,
                             GLsizeiptr size,
                             GLintptr offset)
 {
     ANGLE_TRY(mImpl->setSubData(context, target, data, size, offset));
 
     mIndexRangeCache.invalidateRange(static_cast<unsigned int>(offset), static_cast<unsigned int>(size));
 
+    // Notify when data changes.
+    mImpl->onStateChange(context, angle::SubjectMessage::CONTENTS_CHANGED);
+
     return NoError();
 }
 
 Error Buffer::copyBufferSubData(const Context *context,
                                 Buffer *source,
                                 GLintptr sourceOffset,
                                 GLintptr destOffset,
                                 GLsizeiptr size)
 {
     ANGLE_TRY(
         mImpl->copySubData(context, source->getImplementation(), sourceOffset, destOffset, size));
 
     mIndexRangeCache.invalidateRange(static_cast<unsigned int>(destOffset), static_cast<unsigned int>(size));
 
+    // Notify when data changes.
+    mImpl->onStateChange(context, angle::SubjectMessage::CONTENTS_CHANGED);
+
     return NoError();
 }
 
 Error Buffer::map(const Context *context, GLenum access)
 {
     ASSERT(!mState.mMapped);
 
     mState.mMapPointer = nullptr;
@@ -174,27 +185,36 @@ Error Buffer::unmap(const Context *conte
 
     mState.mMapped      = GL_FALSE;
     mState.mMapPointer  = nullptr;
     mState.mMapOffset   = 0;
     mState.mMapLength   = 0;
     mState.mAccess      = GL_WRITE_ONLY_OES;
     mState.mAccessFlags = 0;
 
+    // Notify when data changes.
+    mImpl->onStateChange(context, angle::SubjectMessage::CONTENTS_CHANGED);
+
     return NoError();
 }
 
-void Buffer::onTransformFeedback()
+void Buffer::onTransformFeedback(const Context *context)
 {
     mIndexRangeCache.clear();
+
+    // Notify when data changes.
+    mImpl->onStateChange(context, angle::SubjectMessage::CONTENTS_CHANGED);
 }
 
-void Buffer::onPixelUnpack()
+void Buffer::onPixelPack(const Context *context)
 {
     mIndexRangeCache.clear();
+
+    // Notify when data changes.
+    mImpl->onStateChange(context, angle::SubjectMessage::CONTENTS_CHANGED);
 }
 
 Error Buffer::getIndexRange(const gl::Context *context,
                             GLenum type,
                             size_t offset,
                             size_t count,
                             bool primitiveRestartEnabled,
                             IndexRange *outRange) const
@@ -207,9 +227,31 @@ Error Buffer::getIndexRange(const gl::Co
     ANGLE_TRY(
         mImpl->getIndexRange(context, type, offset, count, primitiveRestartEnabled, outRange));
 
     mIndexRangeCache.addRange(type, offset, count, primitiveRestartEnabled, *outRange);
 
     return NoError();
 }
 
+bool Buffer::isBound() const
+{
+    return mState.mBindingCount;
+}
+
+bool Buffer::isBoundForTransformFeedbackAndOtherUse() const
+{
+    return mState.mTransformFeedbackBindingCount > 0 &&
+           mState.mTransformFeedbackBindingCount != mState.mBindingCount;
+}
+
+void Buffer::onBindingChanged(bool bound, BufferBinding target)
+{
+    ASSERT(bound || mState.mBindingCount > 0);
+    mState.mBindingCount += bound ? 1 : -1;
+    if (target == BufferBinding::TransformFeedback)
+    {
+        ASSERT(bound || mState.mTransformFeedbackBindingCount > 0);
+        mState.mTransformFeedbackBindingCount += bound ? 1 : -1;
+    }
+}
+
 }  // namespace gl
--- a/gfx/angle/checkout/src/libANGLE/Buffer.h
+++ b/gfx/angle/checkout/src/libANGLE/Buffer.h
@@ -54,16 +54,18 @@ class BufferState final : angle::NonCopy
     BufferUsage mUsage;
     GLint64 mSize;
     GLbitfield mAccessFlags;
     GLenum mAccess;
     GLboolean mMapped;
     void *mMapPointer;
     GLint64 mMapOffset;
     GLint64 mMapLength;
+    int mBindingCount;
+    int mTransformFeedbackBindingCount;
 };
 
 class Buffer final : public RefCountObject, public LabeledObject
 {
   public:
     Buffer(rx::GLImplFactory *factory, GLuint id);
     ~Buffer() override;
     Error onDestroy(const Context *context) override;
@@ -85,18 +87,19 @@ class Buffer final : public RefCountObje
                             Buffer *source,
                             GLintptr sourceOffset,
                             GLintptr destOffset,
                             GLsizeiptr size);
     Error map(const Context *context, GLenum access);
     Error mapRange(const Context *context, GLintptr offset, GLsizeiptr length, GLbitfield access);
     Error unmap(const Context *context, GLboolean *result);
 
-    void onTransformFeedback();
-    void onPixelUnpack();
+    // These are called when another operation changes Buffer data.
+    void onTransformFeedback(const Context *context);
+    void onPixelPack(const Context *context);
 
     Error getIndexRange(const gl::Context *context,
                         GLenum type,
                         size_t offset,
                         size_t count,
                         bool primitiveRestartEnabled,
                         IndexRange *outRange) const;
 
@@ -106,16 +109,20 @@ class Buffer final : public RefCountObje
     GLboolean isMapped() const { return mState.mMapped; }
     void *getMapPointer() const { return mState.mMapPointer; }
     GLint64 getMapOffset() const { return mState.mMapOffset; }
     GLint64 getMapLength() const { return mState.mMapLength; }
     GLint64 getSize() const { return mState.mSize; }
 
     rx::BufferImpl *getImplementation() const { return mImpl; }
 
+    bool isBound() const;
+    bool isBoundForTransformFeedbackAndOtherUse() const;
+    void onBindingChanged(bool bound, BufferBinding target);
+
   private:
     BufferState mState;
     rx::BufferImpl *mImpl;
 
     mutable IndexRangeCache mIndexRangeCache;
 };
 
 }  // namespace gl
--- a/gfx/angle/checkout/src/libANGLE/Caps.cpp
+++ b/gfx/angle/checkout/src/libANGLE/Caps.cpp
@@ -1,42 +1,40 @@
 //
 // Copyright (c) 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 "libANGLE/Caps.h"
 
+#include "common/angleutils.h"
 #include "common/debug.h"
-#include "common/angleutils.h"
 
 #include "libANGLE/formatutils.h"
 
 #include "angle_gl.h"
 
 #include <algorithm>
 #include <sstream>
 
-static void InsertExtensionString(const std::string &extension, bool supported, std::vector<std::string> *extensionVector)
+static void InsertExtensionString(const std::string &extension,
+                                  bool supported,
+                                  std::vector<std::string> *extensionVector)
 {
     if (supported)
     {
         extensionVector->push_back(extension);
     }
 }
 
 namespace gl
 {
 
-TextureCaps::TextureCaps()
-    : texturable(false),
-      filterable(false),
-      renderable(false),
-      sampleCounts()
+TextureCaps::TextureCaps() : texturable(false), filterable(false), renderable(false), sampleCounts()
 {
 }
 
 TextureCaps::TextureCaps(const TextureCaps &other) = default;
 
 TextureCaps::~TextureCaps() = default;
 
 GLuint TextureCaps::getMaxSamples() const
@@ -393,17 +391,19 @@ static bool DetermineRGHalfFloatTextureS
 static bool DetermineRGFloatTextureSupport(const TextureCapsMap &textureCaps)
 {
     constexpr GLenum requiredFormats[] = {
         GL_R32F, GL_RG32F,
     };
     return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
 }
 
-static bool DetermineRGTextureSupport(const TextureCapsMap &textureCaps, bool checkHalfFloatFormats, bool checkFloatFormats)
+static bool DetermineRGTextureSupport(const TextureCapsMap &textureCaps,
+                                      bool checkHalfFloatFormats,
+                                      bool checkFloatFormats)
 {
     if (checkHalfFloatFormats && !DetermineRGHalfFloatTextureSupport(textureCaps))
     {
         return false;
     }
 
     if (checkFloatFormats && !DetermineRGFloatTextureSupport(textureCaps))
     {
@@ -568,39 +568,39 @@ static bool DetermineTextureNorm16Suppor
     };
 
     return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false) &&
            GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true);
 }
 
 void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps)
 {
-    packedDepthStencil = DeterminePackedDepthStencilSupport(textureCaps);
-    rgb8rgba8 = DetermineRGB8AndRGBA8TextureSupport(textureCaps);
-    textureFormatBGRA8888 = DetermineBGRA8TextureSupport(textureCaps);
-    colorBufferHalfFloat      = DetermineColorBufferHalfFloatSupport(textureCaps);
-    textureHalfFloat = DetermineHalfFloatTextureSupport(textureCaps);
+    packedDepthStencil     = DeterminePackedDepthStencilSupport(textureCaps);
+    rgb8rgba8              = DetermineRGB8AndRGBA8TextureSupport(textureCaps);
+    textureFormatBGRA8888  = DetermineBGRA8TextureSupport(textureCaps);
+    colorBufferHalfFloat   = DetermineColorBufferHalfFloatSupport(textureCaps);
+    textureHalfFloat       = DetermineHalfFloatTextureSupport(textureCaps);
     textureHalfFloatLinear = DetermineHalfFloatTextureFilteringSupport(textureCaps);
-    textureFloat = DetermineFloatTextureSupport(textureCaps);
-    textureFloatLinear = DetermineFloatTextureFilteringSupport(textureCaps);
-    textureRG = DetermineRGTextureSupport(textureCaps, textureHalfFloat, textureFloat);
+    textureFloat           = DetermineFloatTextureSupport(textureCaps);
+    textureFloatLinear     = DetermineFloatTextureFilteringSupport(textureCaps);
+    textureRG              = DetermineRGTextureSupport(textureCaps, textureHalfFloat, textureFloat);
     textureCompressionDXT1 = DetermineDXT1TextureSupport(textureCaps);
     textureCompressionDXT3 = DetermineDXT3TextureSupport(textureCaps);
     textureCompressionDXT5 = DetermineDXT5TextureSupport(textureCaps);
     textureCompressionS3TCsRGB = DetermineS3TCsRGBTextureSupport(textureCaps);
-    textureCompressionASTCHDR = DetermineASTCTextureSupport(textureCaps);
-    textureCompressionASTCLDR = textureCompressionASTCHDR;
-    compressedETC1RGB8Texture = DetermineETC1RGB8TextureSupport(textureCaps);
-    sRGB = DetermineSRGBTextureSupport(textureCaps);
-    depthTextures = DetermineDepthTextureSupport(textureCaps);
-    depth32                   = DetermineDepth32Support(textureCaps);
+    textureCompressionASTCHDR  = DetermineASTCTextureSupport(textureCaps);
+    textureCompressionASTCLDR  = textureCompressionASTCHDR;
+    compressedETC1RGB8Texture  = DetermineETC1RGB8TextureSupport(textureCaps);
+    sRGB                       = DetermineSRGBTextureSupport(textureCaps);
+    depthTextures              = DetermineDepthTextureSupport(textureCaps);
+    depth32                    = DetermineDepth32Support(textureCaps);
     colorBufferFloatRGB        = DetermineColorBufferFloatRGBSupport(textureCaps);
     colorBufferFloatRGBA       = DetermineColorBufferFloatRGBASupport(textureCaps);
-    colorBufferFloat = DetermineColorBufferFloatSupport(textureCaps);
-    textureNorm16             = DetermineTextureNorm16Support(textureCaps);
+    colorBufferFloat           = DetermineColorBufferFloatSupport(textureCaps);
+    textureNorm16              = DetermineTextureNorm16Support(textureCaps);
 }
 
 const ExtensionInfoMap &GetExtensionInfoMap()
 {
     auto buildExtensionInfoMap = []() {
         auto enableableExtension = [](ExtensionInfo::ExtensionBool member) {
             ExtensionInfo info;
             info.Requestable      = true;
@@ -864,32 +864,53 @@ Caps::Caps()
       maxGeometryTextureImageUnits(0),
       maxGeometryAtomicCounterBuffers(0),
       maxGeometryAtomicCounters(0),
       maxGeometryShaderStorageBlocks(0),
       maxGeometryShaderInvocations(0),
 
       // Table 20.46 (GL_EXT_geometry_shader)
       maxGeometryImageUniforms(0),
-      maxCombinedGeometryUniformComponents(0)
+      maxCombinedGeometryUniformComponents(0),
+
+      // GLES1 emulation: Table 6.20 / 6.22 (ES 1.1 spec)
+      maxMultitextureUnits(0),
+      maxClipPlanes(0),
+      maxLights(0),
+      maxModelviewMatrixStackDepth(0),
+      maxProjectionMatrixStackDepth(0),
+      maxTextureMatrixStackDepth(0)
+
 {
     for (size_t i = 0; i < 3; ++i)
     {
         maxComputeWorkGroupCount[i] = 0;
         maxComputeWorkGroupSize[i]  = 0;
     }
 }
 
 Caps::Caps(const Caps &other) = default;
 Caps::~Caps()                 = default;
 
 Caps GenerateMinimumCaps(const Version &clientVersion, const Extensions &extensions)
 {
     Caps caps;
 
+    // GLES1 emulation (Minimums taken from Table 6.20 / 6.22 (ES 1.1 spec))
+    if (clientVersion < Version(2, 0))
+    {
+        caps.maxMultitextureUnits = 2;
+        caps.maxLights            = 8;
+        caps.maxClipPlanes        = 1;
+
+        caps.maxModelviewMatrixStackDepth  = 16;
+        caps.maxProjectionMatrixStackDepth = 2;
+        caps.maxTextureMatrixStackDepth    = 2;
+    }
+
     if (clientVersion >= Version(2, 0))
     {
         // Table 6.18
         caps.max2DTextureSize      = 64;
         caps.maxCubeMapTextureSize = 16;
         caps.maxViewportWidth      = caps.max2DTextureSize;
         caps.maxViewportHeight     = caps.max2DTextureSize;
         caps.minAliasedPointSize   = 1;
@@ -1106,18 +1127,17 @@ Caps GenerateMinimumCaps(const Version &
 
     return caps;
 }
 }
 
 namespace egl
 {
 
-Caps::Caps()
-    : textureNPOT(false)
+Caps::Caps() : textureNPOT(false)
 {
 }
 
 DisplayExtensions::DisplayExtensions()
     : createContextRobustness(false),
       d3dShareHandleClientBuffer(false),
       d3dTextureClientBuffer(false),
       surfaceD3DTexture2DShareHandle(false),
@@ -1148,17 +1168,18 @@ DisplayExtensions::DisplayExtensions()
       getSyncValues(false),
       swapBuffersWithDamage(false),
       pixelFormatFloat(false),
       surfacelessContext(false),
       displayTextureShareGroup(false),
       createContextClientArrays(false),
       programCacheControl(false),
       robustResourceInitialization(false),
-      iosurfaceClientBuffer(false)
+      iosurfaceClientBuffer(false),
+      createContextExtensionsEnabled(false)
 {
 }
 
 std::vector<std::string> DisplayExtensions::getStrings() const
 {
     std::vector<std::string> extensionStrings;
 
     // clang-format off
@@ -1194,34 +1215,36 @@ std::vector<std::string> DisplayExtensio
     InsertExtensionString("EGL_EXT_swap_buffers_with_damage",                    swapBuffersWithDamage,              &extensionStrings);
     InsertExtensionString("EGL_EXT_pixel_format_float",                          pixelFormatFloat,                   &extensionStrings);
     InsertExtensionString("EGL_KHR_surfaceless_context",                         surfacelessContext,                 &extensionStrings);
     InsertExtensionString("EGL_ANGLE_display_texture_share_group",               displayTextureShareGroup,           &extensionStrings);
     InsertExtensionString("EGL_ANGLE_create_context_client_arrays",              createContextClientArrays,          &extensionStrings);
     InsertExtensionString("EGL_ANGLE_program_cache_control",                     programCacheControl,                &extensionStrings);
     InsertExtensionString("EGL_ANGLE_robust_resource_initialization",            robustResourceInitialization,       &extensionStrings);
     InsertExtensionString("EGL_ANGLE_iosurface_client_buffer",                   iosurfaceClientBuffer,              &extensionStrings);
+    InsertExtensionString("EGL_ANGLE_create_context_extensions_enabled",         createContextExtensionsEnabled,     &extensionStrings);
     // TODO(jmadill): Enable this when complete.
     //InsertExtensionString("KHR_create_context_no_error",                       createContextNoError,               &extensionStrings);
     // clang-format on
 
     return extensionStrings;
 }
 
-DeviceExtensions::DeviceExtensions()
-    : deviceD3D(false)
+DeviceExtensions::DeviceExtensions() : deviceD3D(false)
 {
 }
 
 std::vector<std::string> DeviceExtensions::getStrings() const
 {
     std::vector<std::string> extensionStrings;
 
+    // clang-format off
     //                   | Extension name                                 | Supported flag                | Output vector   |
     InsertExtensionString("EGL_ANGLE_device_d3d",                          deviceD3D,                      &extensionStrings);
+    // clang-format on
 
     return extensionStrings;
 }
 
 ClientExtensions::ClientExtensions()
     : clientExtensions(false),
       platformBase(false),
       platformDevice(false),
--- a/gfx/angle/checkout/src/libANGLE/Caps.h
+++ b/gfx/angle/checkout/src/libANGLE/Caps.h
@@ -7,21 +7,21 @@
 #ifndef LIBANGLE_CAPS_H_
 #define LIBANGLE_CAPS_H_
 
 #include "angle_gl.h"
 #include "libANGLE/Version.h"
 #include "libANGLE/angletypes.h"
 #include "libANGLE/renderer/Format.h"
 
+#include <array>
 #include <map>
 #include <set>
 #include <string>
 #include <vector>
-#include <array>
 
 namespace gl
 {
 
 struct Extensions;
 
 typedef std::set<GLuint> SupportedSampleSet;
 
@@ -150,22 +150,23 @@ struct Extensions
 
     // GL_OES_texture_float and GL_OES_texture_float_linear
     // Implies that TextureCaps for GL_RGB32F, GL_RGBA32F, GL_ALPHA16F_EXT, GL_LUMINANCE16F_EXT and
     // GL_LUMINANCE_ALPHA16F_EXT exist
     bool textureFloat;
     bool textureFloatLinear;
 
     // GL_EXT_texture_rg
-    // Implies that TextureCaps for GL_R8, GL_RG8 (and floating point R/RG texture formats if floating point extensions
-    // are also present) exist
+    // Implies that TextureCaps for GL_R8, GL_RG8 (and floating point R/RG texture formats if
+    // floating point extensions are also present) exist
     bool textureRG;
 
-    // GL_EXT_texture_compression_dxt1, GL_ANGLE_texture_compression_dxt3 and GL_ANGLE_texture_compression_dxt5
-    // Implies that TextureCaps exist for GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
+    // GL_EXT_texture_compression_dxt1, GL_ANGLE_texture_compression_dxt3 and
+    // GL_ANGLE_texture_compression_dxt5 Implies that TextureCaps exist for
+    // GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
     // GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE and GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE
     bool textureCompressionDXT1;
     bool textureCompressionDXT3;
     bool textureCompressionDXT5;
 
     // GL_EXT_texture_compression_s3tc_srgb
     // Implies that TextureCaps exist for GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,
     // GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, and
@@ -578,16 +579,25 @@ struct Caps
     GLuint maxGeometryAtomicCounters;
     GLuint maxGeometryShaderStorageBlocks;
     GLuint maxGeometryShaderInvocations;
 
     // GL_EXT_geometry_shader (May 31, 2016) Table 20.46: Implementation dependent aggregate shader
     // limits
     GLuint maxGeometryImageUniforms;
     GLuint maxCombinedGeometryUniformComponents;
+
+    // GLES1 emulation: Caps for ES 1.1. Taken from Table 6.20 / 6.22 in the OpenGL ES 1.1 spec.
+    GLuint maxMultitextureUnits;
+    GLuint maxClipPlanes;
+    GLuint maxLights;
+    static constexpr int GlobalMatrixStackDepth = 16;
+    GLuint maxModelviewMatrixStackDepth;
+    GLuint maxProjectionMatrixStackDepth;
+    GLuint maxTextureMatrixStackDepth;
 };
 
 Caps GenerateMinimumCaps(const Version &clientVersion, const Extensions &extensions);
 }
 
 namespace egl
 {
 
@@ -711,16 +721,19 @@ struct DisplayExtensions
     // EGL_ANGLE_program_cache_control
     bool programCacheControl;
 
     // EGL_ANGLE_robust_resource_initialization
     bool robustResourceInitialization;
 
     // EGL_ANGLE_iosurface_client_buffer
     bool iosurfaceClientBuffer;
+
+    // EGL_ANGLE_create_context_extensions_enabled
+    bool createContextExtensionsEnabled;
 };
 
 struct DeviceExtensions
 {
     DeviceExtensions();
 
     // Generate a vector of supported extension strings
     std::vector<std::string> getStrings() const;
@@ -774,9 +787,9 @@ struct ClientExtensions
     bool experimentalPresentPath;
 
     // EGL_KHR_client_get_all_proc_addresses
     bool clientGetAllProcAddresses;
 };
 
 }  // namespace egl
 
-#endif // LIBANGLE_CAPS_H_
+#endif  // LIBANGLE_CAPS_H_
--- a/gfx/angle/checkout/src/libANGLE/Compiler.cpp
+++ b/gfx/angle/checkout/src/libANGLE/Compiler.cpp
@@ -31,16 +31,23 @@ ShShaderSpec SelectShaderSpec(GLint majo
         {
             return isWebGL ? SH_WEBGL3_SPEC : SH_GLES3_1_SPEC;
         }
         else
         {
             return isWebGL ? SH_WEBGL2_SPEC : SH_GLES3_SPEC;
         }
     }
+
+    // GLES1 emulation: Use GLES3 shader spec.
+    if (!isWebGL && majorVersion == 1)
+    {
+        return SH_GLES3_SPEC;
+    }
+
     return isWebGL ? SH_WEBGL_SPEC : SH_GLES2_SPEC;
 }
 
 }  // anonymous namespace
 
 Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state)
     : mImplementation(implFactory->createCompiler()),
       mSpec(SelectShaderSpec(state.getClientMajorVersion(),
@@ -188,52 +195,52 @@ Compiler::~Compiler()
     if (activeCompilerHandles == 0)
     {
         sh::Finalize();
     }
 
     ANGLE_SWALLOW_ERR(mImplementation->release());
 }
 
-ShHandle Compiler::getCompilerHandle(GLenum type)
+ShHandle Compiler::getCompilerHandle(ShaderType type)
 {
     ShHandle *compiler = nullptr;
     switch (type)
     {
-        case GL_VERTEX_SHADER:
+        case ShaderType::Vertex:
             compiler = &mVertexCompiler;
             break;
 
-        case GL_FRAGMENT_SHADER:
+        case ShaderType::Fragment:
             compiler = &mFragmentCompiler;
             break;
-        case GL_COMPUTE_SHADER:
+        case ShaderType::Compute:
             compiler = &mComputeCompiler;
             break;
-        case GL_GEOMETRY_SHADER_EXT:
+        case ShaderType::Geometry:
             compiler = &mGeometryCompiler;
             break;
         default:
             UNREACHABLE();
             return nullptr;
     }
 
     if (!(*compiler))
     {
         if (activeCompilerHandles == 0)
         {
             sh::Initialize();
         }
 
-        *compiler = sh::ConstructCompiler(type, mSpec, mOutputType, &mResources);
+        *compiler = sh::ConstructCompiler(ToGLenum(type), mSpec, mOutputType, &mResources);
         ASSERT(*compiler);
         activeCompilerHandles++;
     }
 
     return *compiler;
 }
 
-const std::string &Compiler::getBuiltinResourcesString(GLenum type)
+const std::string &Compiler::getBuiltinResourcesString(ShaderType type)
 {
     return sh::GetBuiltInResourcesString(getCompilerHandle(type));
 }
 
 }  // namespace gl
--- a/gfx/angle/checkout/src/libANGLE/Compiler.h
+++ b/gfx/angle/checkout/src/libANGLE/Compiler.h
@@ -7,16 +7,17 @@
 // Compiler.h: Defines the gl::Compiler class, abstracting the ESSL compiler
 // that a GL context holds.
 
 #ifndef LIBANGLE_COMPILER_H_
 #define LIBANGLE_COMPILER_H_
 
 #include "GLSLANG/ShaderLang.h"
 #include "libANGLE/Error.h"
+#include "libANGLE/PackedGLEnums_autogen.h"
 #include "libANGLE/RefCountObject.h"
 
 namespace rx
 {
 class CompilerImpl;
 class GLImplFactory;
 }
 
@@ -24,19 +25,19 @@ namespace gl
 {
 class ContextState;
 
 class Compiler final : public RefCountObjectNoID
 {
   public:
     Compiler(rx::GLImplFactory *implFactory, const ContextState &data);
 
-    ShHandle getCompilerHandle(GLenum type);
+    ShHandle getCompilerHandle(ShaderType shaderType);
     ShShaderOutput getShaderOutputType() const { return mOutputType; }
-    const std::string &getBuiltinResourcesString(GLenum type);
+    const std::string &getBuiltinResourcesString(ShaderType type);
 
   private:
     ~Compiler() override;
     std::unique_ptr<rx::CompilerImpl> mImplementation;
     ShShaderSpec mSpec;
     ShShaderOutput mOutputType;
     ShBuiltInResources mResources;
 
--- a/gfx/angle/checkout/src/libANGLE/Context.cpp
+++ b/gfx/angle/checkout/src/libANGLE/Context.cpp
@@ -124,30 +124,24 @@ gl::Error GetQueryObjectParameter(gl::Qu
             return error;
         }
         default:
             UNREACHABLE();
             return gl::InternalError() << "Unreachable Error";
     }
 }
 
-void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
+void MarkTransformFeedbackBufferUsage(const gl::Context *context,
+                                      gl::TransformFeedback *transformFeedback,
+                                      GLsizei count,
+                                      GLsizei instanceCount)
 {
     if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
     {
-        for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
-             tfBufferIndex++)
-        {
-            const gl::OffsetBindingPointer<gl::Buffer> &buffer =
-                transformFeedback->getIndexedBuffer(tfBufferIndex);
-            if (buffer.get() != nullptr)
-            {
-                buffer->onTransformFeedback();
-            }
-        }
+        transformFeedback->onVerticesDrawn(context, count, instanceCount);
     }
 }
 
 // Attribute map queries.
 EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
 {
     return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
 }
@@ -159,18 +153,18 @@ EGLint GetClientMinorVersion(const egl::
 
 gl::Version GetClientVersion(const egl::AttributeMap &attribs)
 {
     return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
 }
 
 GLenum GetResetStrategy(const egl::AttributeMap &attribs)
 {
-    EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
-                                   EGL_NO_RESET_NOTIFICATION);
+    EGLAttrib attrib =
+        attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION);
     switch (attrib)
     {
         case EGL_NO_RESET_NOTIFICATION:
             return GL_NO_RESET_NOTIFICATION_EXT;
         case EGL_LOSE_CONTEXT_ON_RESET:
             return GL_LOSE_CONTEXT_ON_RESET_EXT;
         default:
             UNREACHABLE();
@@ -196,16 +190,23 @@ bool GetNoError(const egl::AttributeMap 
     return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
 }
 
 bool GetWebGLContext(const egl::AttributeMap &attribs)
 {
     return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
 }
 
+bool GetExtensionsEnabled(const egl::AttributeMap &attribs, bool webGLContext)
+{
+    // If the context is WebGL, extensions are disabled by default
+    EGLAttrib defaultValue = webGLContext ? EGL_FALSE : EGL_TRUE;
+    return (attribs.get(EGL_EXTENSIONS_ENABLED_ANGLE, defaultValue) == EGL_TRUE);
+}
+
 bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
 {
     return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
 }
 
 bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
 {
     return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
@@ -259,44 +260,51 @@ namespace gl
 
 Context::Context(rx::EGLImplFactory *implFactory,
                  const egl::Config *config,
                  const Context *shareContext,
                  TextureManager *shareTextures,
                  MemoryProgramCache *memoryProgramCache,
                  const egl::AttributeMap &attribs,
                  const egl::DisplayExtensions &displayExtensions)
-
-    : ValidationContext(shareContext,
-                        shareTextures,
-                        GetClientVersion(attribs),
-                        &mGLState,
-                        mCaps,
-                        mTextureCaps,
-                        mExtensions,
-                        mLimitations,
-                        GetNoError(attribs)),
+    : mState(reinterpret_cast<ContextID>(this),
+             shareContext ? &shareContext->mState : nullptr,
+             shareTextures,
+             GetClientVersion(attribs),
+             &mGLState,
+             mCaps,
+             mTextureCaps,
+             mExtensions,
+             mLimitations),
+      mSkipValidation(GetNoError(attribs)),
+      mDisplayTextureShareGroup(shareTextures != nullptr),
+      mSavedArgsType(nullptr),
       mImplementation(implFactory->createContext(mState)),
       mCompiler(),
       mConfig(config),
       mClientType(EGL_OPENGL_ES_API),
       mHasBeenCurrent(false),
       mContextLost(false),
       mResetStatus(GL_NO_ERROR),
       mContextLostForced(false),
       mResetStrategy(GetResetStrategy(attribs)),
       mRobustAccess(GetRobustAccess(attribs)),
       mCurrentSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
       mCurrentDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
       mSurfacelessFramebuffer(nullptr),
       mWebGLContext(GetWebGLContext(attribs)),
+      mExtensionsEnabled(GetExtensionsEnabled(attribs, mWebGLContext)),
       mMemoryProgramCache(memoryProgramCache),
       mScratchBuffer(1000u),
       mZeroFilledBuffer(1000u)
 {
+    // Needed to solve a Clang warning of unused variables.
+    UNUSED_VARIABLE(mSavedArgsType);
+    UNUSED_VARIABLE(mParamsBuffer);
+
     mImplementation->setMemoryProgramCache(memoryProgramCache);
 
     bool robustResourceInit = GetRobustResourceInit(attribs);
     initCaps(displayExtensions, robustResourceInit);
     initWorkarounds();
 
     mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
                         GetClientArraysEnabled(attribs), robustResourceInit,
@@ -305,61 +313,60 @@ Context::Context(rx::EGLImplFactory *imp
     mFenceNVHandleAllocator.setBaseHandle(0);
 
     // [OpenGL ES 2.0.24] section 3.7 page 83:
     // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have two-dimensional
     // and cube map texture state vectors respectively associated with them.
     // In order that access to these initial textures not be lost, they are treated as texture
     // objects all of whose names are 0.
 
-    Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
-    mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
-
-    Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
-    mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
+    Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, TextureType::_2D);
+    mZeroTextures[TextureType::_2D].set(this, zeroTexture2D);
+
+    Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, TextureType::CubeMap);
+    mZeroTextures[TextureType::CubeMap].set(this, zeroTextureCube);
 
     if (getClientVersion() >= Version(3, 0))
     {
         // TODO: These could also be enabled via extension
-        Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
-        mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
-
-        Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
-        mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
+        Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, TextureType::_3D);
+        mZeroTextures[TextureType::_3D].set(this, zeroTexture3D);
+
+        Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, TextureType::_2DArray);
+        mZeroTextures[TextureType::_2DArray].set(this, zeroTexture2DArray);
     }
     if (getClientVersion() >= Version(3, 1))
     {
         Texture *zeroTexture2DMultisample =
-            new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
-        mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
+            new Texture(mImplementation.get(), 0, TextureType::_2DMultisample);
+        mZeroTextures[TextureType::_2DMultisample].set(this, zeroTexture2DMultisample);
 
         for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
         {
             bindBufferRange(BufferBinding::AtomicCounter, i, 0, 0, 0);
         }
 
         for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
         {
             bindBufferRange(BufferBinding::ShaderStorage, i, 0, 0, 0);
         }
     }
 
     const Extensions &nativeExtensions = mImplementation->getNativeExtensions();
     if (nativeExtensions.textureRectangle)
     {
         Texture *zeroTextureRectangle =
-            new Texture(mImplementation.get(), 0, GL_TEXTURE_RECTANGLE_ANGLE);
-        mZeroTextures[GL_TEXTURE_RECTANGLE_ANGLE].set(this, zeroTextureRectangle);
+            new Texture(mImplementation.get(), 0, TextureType::Rectangle);
+        mZeroTextures[TextureType::Rectangle].set(this, zeroTextureRectangle);
     }
 
     if (nativeExtensions.eglImageExternal || nativeExtensions.eglStreamConsumerExternal)
     {
-        Texture *zeroTextureExternal =
-            new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
-        mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
+        Texture *zeroTextureExternal = new Texture(mImplementation.get(), 0, TextureType::External);
+        mZeroTextures[TextureType::External].set(this, zeroTextureExternal);
     }
 
     mGLState.initializeZeroTextures(this, mZeroTextures);
 
     bindVertexArray(0);
 
     if (getClientVersion() >= Version(3, 0))
     {
@@ -413,22 +420,28 @@ Context::Context(rx::EGLImplFactory *imp
 
     // TODO(xinghua.cao@intel.com): add other dirty bits and dirty objects.
     mComputeDirtyBits.set(State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
     mComputeDirtyBits.set(State::DIRTY_BIT_PROGRAM_BINDING);
     mComputeDirtyBits.set(State::DIRTY_BIT_PROGRAM_EXECUTABLE);
     mComputeDirtyBits.set(State::DIRTY_BIT_TEXTURE_BINDINGS);
     mComputeDirtyBits.set(State::DIRTY_BIT_SAMPLER_BINDINGS);
     mComputeDirtyBits.set(State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING);
+    mComputeDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_TEXTURES);
 
     handleError(mImplementation->initialize());
 }
 
 egl::Error Context::onDestroy(const egl::Display *display)
 {
+    // Delete the Surface first to trigger a finish() in Vulkan.
+    SafeDelete(mSurfacelessFramebuffer);
+
+    ANGLE_TRY(releaseSurface(display));
+
     for (auto fence : mFenceNVMap)
     {
         SafeDelete(fence.second);
     }
     mFenceNVMap.clear();
 
     for (auto query : mQueryMap)
     {
@@ -452,26 +465,25 @@ egl::Error Context::onDestroy(const egl:
     {
         if (transformFeedback.second != nullptr)
         {
             transformFeedback.second->release(this);
         }
     }
     mTransformFeedbackMap.clear();
 
-    for (auto &zeroTexture : mZeroTextures)
-    {
-        ANGLE_TRY(zeroTexture.second->onDestroy(this));
-        zeroTexture.second.set(this, nullptr);
-    }
-    mZeroTextures.clear();
-
-    SafeDelete(mSurfacelessFramebuffer);
-
-    ANGLE_TRY(releaseSurface(display));
+    for (BindingPointer<Texture> &zeroTexture : mZeroTextures)
+    {
+        if (zeroTexture.get() != nullptr)
+        {
+            ANGLE_TRY(zeroTexture->onDestroy(this));
+            zeroTexture.set(this, nullptr);
+        }
+    }
+
     releaseShaderCompiler();
 
     mGLState.reset(this);
 
     mState.mBuffers->release(this);
     mState.mShaderPrograms->release(this);
     mState.mTextures->release(this);
     mState.mRenderbuffers->release(this);
@@ -593,32 +605,32 @@ GLuint Context::createBuffer()
     return mState.mBuffers->createBuffer();
 }
 
 GLuint Context::createProgram()
 {
     return mState.mShaderPrograms->createProgram(mImplementation.get());
 }
 
-GLuint Context::createShader(GLenum type)
+GLuint Context::createShader(ShaderType type)
 {
     return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
 }
 
 GLuint Context::createTexture()
 {
     return mState.mTextures->createTexture();
 }
 
 GLuint Context::createRenderbuffer()
 {
     return mState.mRenderbuffers->createRenderbuffer();
 }
 
-GLuint Context::createPaths(GLsizei range)
+GLuint Context::genPaths(GLsizei range)
 {
     auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
     if (resultOrError.isError())
     {
         handleError(resultOrError.getError());
         return 0;
     }
     return resultOrError.getResult();
@@ -640,30 +652,31 @@ void Context::genFencesNV(GLsizei n, GLu
     }
 }
 
 GLuint Context::createProgramPipeline()
 {
     return mState.mPipelines->createProgramPipeline();
 }
 
-GLuint Context::createShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings)
+GLuint Context::createShaderProgramv(ShaderType type, GLsizei count, const GLchar *const *strings)
 {
     UNIMPLEMENTED();
     return 0u;
 }
 
-void Context::deleteBuffer(GLuint buffer)
-{
-    if (mState.mBuffers->getBuffer(buffer))
+void Context::deleteBuffer(GLuint bufferName)
+{
+    Buffer *buffer = mState.mBuffers->getBuffer(bufferName);
+    if (buffer)
     {
         detachBuffer(buffer);
     }
 
-    mState.mBuffers->deleteObject(this, buffer);
+    mState.mBuffers->deleteObject(this, bufferName);
 }
 
 void Context::deleteShader(GLuint shader)
 {
     mState.mShaderPrograms->deleteShader(this, shader);
 }
 
 void Context::deleteProgram(GLuint program)
@@ -710,36 +723,36 @@ void Context::deleteProgramPipeline(GLui
     mState.mPipelines->deleteObject(this, pipeline);
 }
 
 void Context::deletePaths(GLuint first, GLsizei range)
 {
     mState.mPaths->deletePaths(first, range);
 }
 
-bool Context::hasPathData(GLuint path) const
+bool Context::isPath(GLuint path) const
 {
     const auto *pathObj = mState.mPaths->getPath(path);
     if (pathObj == nullptr)
         return false;
 
     return pathObj->hasPathData();
 }
 
-bool Context::hasPath(GLuint path) const
+bool Context::isPathGenerated(GLuint path) const
 {
     return mState.mPaths->hasPath(path);
 }
 
-void Context::setPathCommands(GLuint path,
-                              GLsizei numCommands,
-                              const GLubyte *commands,
-                              GLsizei numCoords,
-                              GLenum coordType,
-                              const void *coords)
+void Context::pathCommands(GLuint path,
+                           GLsizei numCommands,
+                           const GLubyte *commands,
+                           GLsizei numCoords,
+                           GLenum coordType,
+                           const void *coords)
 {
     auto *pathObject = mState.mPaths->getPath(path);
 
     handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
 }
 
 void Context::pathParameterf(GLuint path, GLenum pname, GLfloat value)
 {
@@ -804,17 +817,17 @@ void Context::getPathParameterfv(GLuint 
 void Context::getPathParameteriv(GLuint path, GLenum pname, GLint *value)
 {
     GLfloat val = 0.0f;
     getPathParameterfv(path, pname, value != nullptr ? &val : nullptr);
     if (value)
         *value = static_cast<GLint>(val);
 }
 
-void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
+void Context::pathStencilFunc(GLenum func, GLint ref, GLuint mask)
 {
     mGLState.setPathStencilFunc(func, ref, mask);
 }
 
 void Context::deleteFramebuffer(GLuint framebuffer)
 {
     if (mState.mFramebuffers->getFramebuffer(framebuffer))
     {
@@ -961,17 +974,17 @@ void Context::getObjectPtrLabel(const vo
     GetObjectLabelBase(objectLabel, bufSize, length, label);
 }
 
 bool Context::isSampler(GLuint samplerName) const
 {
     return mState.mSamplers->isSampler(samplerName);
 }
 
-void Context::bindTexture(GLenum target, GLuint handle)
+void Context::bindTexture(TextureType target, GLuint handle)
 {
     Texture *texture = nullptr;
 
     if (handle == 0)
     {
         texture = mZeroTextures[target].get();
     }
     else
@@ -1113,36 +1126,81 @@ void Context::getQueryiv(GLenum target, 
             }
             break;
         default:
             UNREACHABLE();
             return;
     }
 }
 
+void Context::getQueryivRobust(GLenum target,
+                               GLenum pname,
+                               GLsizei bufSize,
+                               GLsizei *length,
+                               GLint *params)
+{
+    getQueryiv(target, pname, params);
+}
+
 void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
 {
     handleError(GetQueryObjectParameter(getQuery(id), pname, params));
 }
 
+void Context::getQueryObjectivRobust(GLuint id,
+                                     GLenum pname,
+                                     GLsizei bufSize,
+                                     GLsizei *length,
+                                     GLint *params)
+{
+    getQueryObjectiv(id, pname, params);
+}
+
 void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
 {
     handleError(GetQueryObjectParameter(getQuery(id), pname, params));
 }
 
+void Context::getQueryObjectuivRobust(GLuint id,
+                                      GLenum pname,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      GLuint *params)
+{
+    getQueryObjectuiv(id, pname, params);
+}
+
 void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
 {
     handleError(GetQueryObjectParameter(getQuery(id), pname, params));
 }
 
+void Context::getQueryObjecti64vRobust(GLuint id,
+                                       GLenum pname,
+                                       GLsizei bufSize,
+                                       GLsizei *length,
+                                       GLint64 *params)
+{
+    getQueryObjecti64v(id, pname, params);
+}
+
 void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
 {
     handleError(GetQueryObjectParameter(getQuery(id), pname, params));
 }
 
+void Context::getQueryObjectui64vRobust(GLuint id,
+                                        GLenum pname,
+                                        GLsizei bufSize,
+                                        GLsizei *length,
+                                        GLuint64 *params)
+{
+    getQueryObjectui64v(id, pname, params);
+}
+
 Framebuffer *Context::getFramebuffer(GLuint handle) const
 {
     return mState.mFramebuffers->getFramebuffer(handle);
 }
 
 FenceNV *Context::getFenceNV(GLuint handle)
 {
     return mFenceNVMap.query(handle);
@@ -1165,23 +1223,23 @@ Query *Context::getQuery(GLuint handle, 
     return query;
 }
 
 Query *Context::getQuery(GLuint handle) const
 {
     return mQueryMap.query(handle);
 }
 
-Texture *Context::getTargetTexture(GLenum target) const
-{
-    ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
-    return mGLState.getTargetTexture(target);
-}
-
-Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
+Texture *Context::getTargetTexture(TextureType type) const
+{
+    ASSERT(ValidTextureTarget(this, type) || ValidTextureExternalTarget(this, type));
+    return mGLState.getTargetTexture(type);
+}
+
+Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
 {
     return mGLState.getSamplerTexture(sampler, type);
 }
 
 Compiler *Context::getCompiler() const
 {
     if (mCompiler.get() == nullptr)
     {
@@ -1226,19 +1284,28 @@ void Context::getFloatvImpl(GLenum pname
             break;
         case GL_MAX_TEXTURE_LOD_BIAS:
             *params = mCaps.maxLODBias;
             break;
 
         case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
         case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
         {
-            ASSERT(mExtensions.pathRendering);
-            const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
-            memcpy(params, m, 16 * sizeof(GLfloat));
+            // GLES1 emulation: // GL_PATH_(MODELVIEW|PROJECTION)_MATRIX_CHROMIUM collides with the
+            // GLES1 constants for modelview/projection matrix.
+            if (getClientVersion() < Version(2, 0))
+            {
+                mGLState.getFloatv(pname, params);
+            }
+            else
+            {
+                ASSERT(mExtensions.pathRendering);
+                const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
+                memcpy(params, m, 16 * sizeof(GLfloat));
+            }
         }
         break;
 
         default:
             mGLState.getFloatv(pname, params);
             break;
     }
 }
@@ -1580,18 +1647,31 @@ void Context::getIntegervImpl(GLenum pna
             *params = mCaps.maxGeometryAtomicCounters;
             break;
         case GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT:
             *params = mCaps.maxGeometryImageUniforms;
             break;
         case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT:
             *params = mCaps.maxGeometryShaderStorageBlocks;
             break;
+        // GLES1 emulation: Caps queries
+        case GL_MAX_TEXTURE_UNITS:
+            *params = mCaps.maxMultitextureUnits;
+            break;
+        case GL_MAX_MODELVIEW_STACK_DEPTH:
+            *params = mCaps.maxModelviewMatrixStackDepth;
+            break;
+        case GL_MAX_PROJECTION_STACK_DEPTH:
+            *params = mCaps.maxProjectionMatrixStackDepth;
+            break;
+        case GL_MAX_TEXTURE_STACK_DEPTH:
+            *params = mCaps.maxTextureMatrixStackDepth;
+            break;
         default:
-            mGLState.getIntegerv(this, pname, params);
+            handleError(mGLState.getIntegerv(this, pname, params));
             break;
     }
 }
 
 void Context::getInteger64vImpl(GLenum pname, GLint64 *params)
 {
     // Queries about context capabilities and maximums are answered by Context.
     // Queries about current GL state values are answered by State.
@@ -1627,16 +1707,24 @@ void Context::getInteger64vImpl(GLenum p
     }
 }
 
 void Context::getPointerv(GLenum pname, void **params) const
 {
     mGLState.getPointerv(pname, params);
 }
 
+void Context::getPointervRobustANGLERobust(GLenum pname,
+                                           GLsizei bufSize,
+                                           GLsizei *length,
+                                           void **params)
+{
+    UNIMPLEMENTED();
+}
+
 void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
 {
     // Queries about context capabilities and maximums are answered by Context.
     // Queries about current GL state values are answered by State.
 
     GLenum nativeType;
     unsigned int numParams;
     bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
@@ -1659,16 +1747,25 @@ void Context::getIntegeri_v(GLenum targe
         }
     }
     else
     {
         CastIndexedStateValues(this, nativeType, target, index, numParams, data);
     }
 }
 
+void Context::getIntegeri_vRobust(GLenum target,
+                                  GLuint index,
+                                  GLsizei bufSize,
+                                  GLsizei *length,
+                                  GLint *data)
+{
+    getIntegeri_v(target, index, data);
+}
+
 void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
 {
     // Queries about context capabilities and maximums are answered by Context.
     // Queries about current GL state values are answered by State.
 
     GLenum nativeType;
     unsigned int numParams;
     bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
@@ -1679,16 +1776,25 @@ void Context::getInteger64i_v(GLenum tar
         mGLState.getInteger64i_v(target, index, data);
     }
     else
     {
         CastIndexedStateValues(this, nativeType, target, index, numParams, data);
     }
 }
 
+void Context::getInteger64i_vRobust(GLenum target,
+                                    GLuint index,
+                                    GLsizei bufSize,
+                                    GLsizei *length,
+                                    GLint64 *data)
+{
+    getInteger64i_v(target, index, data);
+}
+
 void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
 {
     // Queries about context capabilities and maximums are answered by Context.
     // Queries about current GL state values are answered by State.
 
     GLenum nativeType;
     unsigned int numParams;
     bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
@@ -1699,116 +1805,243 @@ void Context::getBooleani_v(GLenum targe
         mGLState.getBooleani_v(target, index, data);
     }
     else
     {
         CastIndexedStateValues(this, nativeType, target, index, numParams, data);
     }
 }
 
+void Context::getBooleani_vRobust(GLenum target,
+                                  GLuint index,
+                                  GLsizei bufSize,
+                                  GLsizei *length,
+                                  GLboolean *data)
+{
+    getBooleani_v(target, index, data);
+}
+
 void Context::getBufferParameteriv(BufferBinding target, GLenum pname, GLint *params)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     QueryBufferParameteriv(buffer, pname, params);
 }
 
+void Context::getBufferParameterivRobust(BufferBinding target,
+                                         GLenum pname,
+                                         GLsizei bufSize,
+                                         GLsizei *length,
+                                         GLint *params)
+{
+    getBufferParameteriv(target, pname, params);
+}
+
 void Context::getFramebufferAttachmentParameteriv(GLenum target,
                                                   GLenum attachment,
                                                   GLenum pname,
                                                   GLint *params)
 {
     const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
     QueryFramebufferAttachmentParameteriv(this, framebuffer, attachment, pname, params);
 }
 
+void Context::getFramebufferAttachmentParameterivRobust(GLenum target,
+                                                        GLenum attachment,
+                                                        GLenum pname,
+                                                        GLsizei bufSize,
+                                                        GLsizei *length,
+                                                        GLint *params)
+{
+    getFramebufferAttachmentParameteriv(target, attachment, pname, params);
+}
+
 void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
 {
     Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
     QueryRenderbufferiv(this, renderbuffer, pname, params);
 }
 
-void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
+void Context::getRenderbufferParameterivRobust(GLenum target,
+                                               GLenum pname,
+                                               GLsizei bufSize,
+                                               GLsizei *length,
+                                               GLint *params)
+{
+    getRenderbufferParameteriv(target, pname, params);
+}
+
+void Context::getTexParameterfv(TextureType target, GLenum pname, GLfloat *params)
 {
     Texture *texture = getTargetTexture(target);
     QueryTexParameterfv(texture, pname, params);
 }
 
-void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
+void Context::getTexParameterfvRobust(TextureType target,
+                                      GLenum pname,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      GLfloat *params)
+{
+    getTexParameterfv(target, pname, params);
+}
+
+void Context::getTexParameteriv(TextureType target, GLenum pname, GLint *params)
 {
     Texture *texture = getTargetTexture(target);
     QueryTexParameteriv(texture, pname, params);
 }
 
-void Context::getTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
-{
-    Texture *texture =
-        getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+void Context::getTexParameterivRobust(TextureType target,
+                                      GLenum pname,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      GLint *params)
+{
+    getTexParameteriv(target, pname, params);
+}
+
+void Context::getTexParameterIivRobust(TextureType target,
+                                       GLenum pname,
+                                       GLsizei bufSize,
+                                       GLsizei *length,
+                                       GLint *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getTexParameterIuivRobust(TextureType target,
+                                        GLenum pname,
+                                        GLsizei bufSize,
+                                        GLsizei *length,
+                                        GLuint *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getTexLevelParameteriv(TextureTarget target, GLint level, GLenum pname, GLint *params)
+{
+    Texture *texture = getTargetTexture(TextureTargetToType(target));
     QueryTexLevelParameteriv(texture, target, level, pname, params);
 }
 
-void Context::getTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)
-{
-    Texture *texture =
-        getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+void Context::getTexLevelParameterivRobust(TextureTarget target,
+                                           GLint level,
+                                           GLenum pname,
+                                           GLsizei bufSize,
+                                           GLsizei *length,
+                                           GLint *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getTexLevelParameterfv(TextureTarget target,
+                                     GLint level,
+                                     GLenum pname,
+                                     GLfloat *params)
+{
+    Texture *texture = getTargetTexture(TextureTargetToType(target));
     QueryTexLevelParameterfv(texture, target, level, pname, params);
 }
 
-void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
+void Context::getTexLevelParameterfvRobust(TextureTarget target,
+                                           GLint level,
+                                           GLenum pname,
+                                           GLsizei bufSize,
+                                           GLsizei *length,
+                                           GLfloat *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::texParameterf(TextureType target, GLenum pname, GLfloat param)
 {
     Texture *texture = getTargetTexture(target);
     SetTexParameterf(this, texture, pname, param);
     onTextureChange(texture);
 }
 
-void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
+void Context::texParameterfv(TextureType target, GLenum pname, const GLfloat *params)
 {
     Texture *texture = getTargetTexture(target);
     SetTexParameterfv(this, texture, pname, params);
     onTextureChange(texture);
 }
 
-void Context::texParameteri(GLenum target, GLenum pname, GLint param)
+void Context::texParameterfvRobust(TextureType target,
+                                   GLenum pname,
+                                   GLsizei bufSize,
+                                   const GLfloat *params)
+{
+    texParameterfv(target, pname, params);
+}
+
+void Context::texParameteri(TextureType target, GLenum pname, GLint param)
 {
     Texture *texture = getTargetTexture(target);
     SetTexParameteri(this, texture, pname, param);
     onTextureChange(texture);
 }
 
-void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
+void Context::texParameteriv(TextureType target, GLenum pname, const GLint *params)
 {
     Texture *texture = getTargetTexture(target);
     SetTexParameteriv(this, texture, pname, params);
     onTextureChange(texture);
 }
 
+void Context::texParameterivRobust(TextureType target,
+                                   GLenum pname,
+                                   GLsizei bufSize,
+                                   const GLint *params)
+{
+    texParameteriv(target, pname, params);
+}
+
+void Context::texParameterIivRobust(TextureType target,
+                                    GLenum pname,
+                                    GLsizei bufSize,
+                                    const GLint *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::texParameterIuivRobust(TextureType target,
+                                     GLenum pname,
+                                     GLsizei bufSize,
+                                     const GLuint *params)
+{
+    UNIMPLEMENTED();
+}
+
 void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
 {
     // No-op if zero count
     if (count == 0)
     {
         return;
     }
 
     ANGLE_CONTEXT_TRY(prepareForDraw());
     ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
-    MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
+    MarkTransformFeedbackBufferUsage(this, mGLState.getCurrentTransformFeedback(), count, 1);
 }
 
 void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
 {
     // No-op if zero count
     if (count == 0 || instanceCount == 0)
     {
         return;
     }
 
     ANGLE_CONTEXT_TRY(prepareForDraw());
     ANGLE_CONTEXT_TRY(
         mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
-    MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
+    MarkTransformFeedbackBufferUsage(this, mGLState.getCurrentTransformFeedback(), count,
+                                     instanceCount);
 }
 
 void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
 {
     // No-op if zero count
     if (count == 0)
     {
         return;
@@ -1906,137 +2139,137 @@ void Context::popGroupMarker()
 void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
 {
     Program *programObject = getProgram(program);
     ASSERT(programObject);
 
     programObject->bindUniformLocation(location, name);
 }
 
-void Context::setCoverageModulation(GLenum components)
+void Context::coverageModulation(GLenum components)
 {
     mGLState.setCoverageModulation(components);
 }
 
-void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
+void Context::matrixLoadf(GLenum matrixMode, const GLfloat *matrix)
 {
     mGLState.loadPathRenderingMatrix(matrixMode, matrix);
 }
 
-void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
+void Context::matrixLoadIdentity(GLenum matrixMode)
 {
     GLfloat I[16];
     angle::Matrix<GLfloat>::setToIdentity(I);
 
     mGLState.loadPathRenderingMatrix(matrixMode, I);
 }
 
 void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
 {
     const auto *pathObj = mState.mPaths->getPath(path);
     if (!pathObj)
         return;
 
     // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(syncState());
 
     mImplementation->stencilFillPath(pathObj, fillMode, mask);
 }
 
 void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
 {
     const auto *pathObj = mState.mPaths->getPath(path);
     if (!pathObj)
         return;
 
     // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(syncState());
 
     mImplementation->stencilStrokePath(pathObj, reference, mask);
 }
 
 void Context::coverFillPath(GLuint path, GLenum coverMode)
 {
     const auto *pathObj = mState.mPaths->getPath(path);
     if (!pathObj)
         return;
 
     // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(syncState());
 
     mImplementation->coverFillPath(pathObj, coverMode);
 }
 
 void Context::coverStrokePath(GLuint path, GLenum coverMode)
 {
     const auto *pathObj = mState.mPaths->getPath(path);
     if (!pathObj)
         return;
 
     // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(syncState());
 
     mImplementation->coverStrokePath(pathObj, coverMode);
 }
 
 void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
 {
     const auto *pathObj = mState.mPaths->getPath(path);
     if (!pathObj)
         return;
 
     // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(syncState());
 
     mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
 }
 
 void Context::stencilThenCoverStrokePath(GLuint path,
                                          GLint reference,
                                          GLuint mask,
                                          GLenum coverMode)
 {
     const auto *pathObj = mState.mPaths->getPath(path);
     if (!pathObj)
         return;
 
     // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(syncState());
 
     mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
 }
 
 void Context::coverFillPathInstanced(GLsizei numPaths,
                                      GLenum pathNameType,
                                      const void *paths,
                                      GLuint pathBase,
                                      GLenum coverMode,
                                      GLenum transformType,
                                      const GLfloat *transformValues)
 {
     const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
 
     // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(syncState());
 
     mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
 }
 
 void Context::coverStrokePathInstanced(GLsizei numPaths,
                                        GLenum pathNameType,
                                        const void *paths,
                                        GLuint pathBase,
                                        GLenum coverMode,
                                        GLenum transformType,
                                        const GLfloat *transformValues)
 {
     const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
 
     // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(syncState());
 
     mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
                                               transformValues);
 }
 
 void Context::stencilFillPathInstanced(GLsizei numPaths,
                                        GLenum pathNameType,
                                        const void *paths,
@@ -2044,17 +2277,17 @@ void Context::stencilFillPathInstanced(G
                                        GLenum fillMode,
                                        GLuint mask,
                                        GLenum transformType,
                                        const GLfloat *transformValues)
 {
     const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
 
     // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(syncState());
 
     mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
                                               transformValues);
 }
 
 void Context::stencilStrokePathInstanced(GLsizei numPaths,
                                          GLenum pathNameType,
                                          const void *paths,
@@ -2062,17 +2295,17 @@ void Context::stencilStrokePathInstanced
                                          GLint reference,
                                          GLuint mask,
                                          GLenum transformType,
                                          const GLfloat *transformValues)
 {
     const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
 
     // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(syncState());
 
     mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
                                                 transformValues);
 }
 
 void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
                                                 GLenum pathNameType,
                                                 const void *paths,
@@ -2081,17 +2314,17 @@ void Context::stencilThenCoverFillPathIn
                                                 GLuint mask,
                                                 GLenum coverMode,
                                                 GLenum transformType,
                                                 const GLfloat *transformValues)
 {
     const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
 
     // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(syncState());
 
     mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
                                                        transformType, transformValues);
 }
 
 void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
                                                   GLenum pathNameType,
                                                   const void *paths,
@@ -2100,17 +2333,17 @@ void Context::stencilThenCoverStrokePath
                                                   GLuint mask,
                                                   GLenum coverMode,
                                                   GLenum transformType,
                                                   const GLfloat *transformValues)
 {
     const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
 
     // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(syncState());
 
     mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
                                                          transformType, transformValues);
 }
 
 void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
 {
     auto *programObject = getProgram(program);
@@ -2172,16 +2405,26 @@ void Context::getProgramInterfaceiv(GLui
                                     GLenum programInterface,
                                     GLenum pname,
                                     GLint *params)
 {
     const auto *programObject = getProgram(program);
     QueryProgramInterfaceiv(programObject, programInterface, pname, params);
 }
 
+void Context::getProgramInterfaceivRobust(GLuint program,
+                                          GLenum programInterface,
+                                          GLenum pname,
+                                          GLsizei bufSize,
+                                          GLsizei *length,
+                                          GLint *params)
+{
+    UNIMPLEMENTED();
+}
+
 void Context::handleError(const Error &error)
 {
     if (error.isError())
     {
         GLenum code = error.getCode();
         mErrors.insert(code);
         if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
         {
@@ -2341,17 +2584,17 @@ void Context::detachTexture(GLuint textu
 {
     // Simple pass-through to State's detachTexture method, as textures do not require
     // allocation map management either here or in the resource manager at detach time.
     // Zero textures are held by the Context, and we don't attempt to request them from
     // the State.
     mGLState.detachTexture(this, mZeroTextures, texture);
 }
 
-void Context::detachBuffer(GLuint buffer)
+void Context::detachBuffer(Buffer *buffer)
 {
     // Simple pass-through to State's detachBuffer method, since
     // only buffer attachments to container objects that are bound to the current context
     // should be detached. And all those are available in State.
 
     // [OpenGL ES 3.2] section 5.1.2 page 45:
     // Attachments to unbound container objects, such as
     // deletion of a buffer attached to a vertex array object which is not bound to the context,
@@ -2442,48 +2685,116 @@ void Context::samplerParameteri(GLuint s
 void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
 {
     Sampler *samplerObject =
         mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
     SetSamplerParameteriv(samplerObject, pname, param);
     mGLState.setObjectDirty(GL_SAMPLER);
 }
 
+void Context::samplerParameterivRobust(GLuint sampler,
+                                       GLenum pname,
+                                       GLsizei bufSize,
+                                       const GLint *param)
+{
+    samplerParameteriv(sampler, pname, param);
+}
+
+void Context::samplerParameterIivRobust(GLuint sampler,
+                                        GLenum pname,
+                                        GLsizei bufSize,
+                                        const GLint *param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::samplerParameterIuivRobust(GLuint sampler,
+                                         GLenum pname,
+                                         GLsizei bufSize,
+                                         const GLuint *param)
+{
+    UNIMPLEMENTED();
+}
+
 void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
 {
     Sampler *samplerObject =
         mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
     SetSamplerParameterf(samplerObject, pname, param);
     mGLState.setObjectDirty(GL_SAMPLER);
 }
 
 void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
 {
     Sampler *samplerObject =
         mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
     SetSamplerParameterfv(samplerObject, pname, param);
     mGLState.setObjectDirty(GL_SAMPLER);
 }
 
+void Context::samplerParameterfvRobust(GLuint sampler,
+                                       GLenum pname,
+                                       GLsizei bufSize,
+                                       const GLfloat *param)
+{
+    samplerParameterfv(sampler, pname, param);
+}
+
 void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
 {
     const Sampler *samplerObject =
         mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
     QuerySamplerParameteriv(samplerObject, pname, params);
     mGLState.setObjectDirty(GL_SAMPLER);
 }
 
+void Context::getSamplerParameterivRobust(GLuint sampler,
+                                          GLenum pname,
+                                          GLsizei bufSize,
+                                          GLsizei *length,
+                                          GLint *params)
+{
+    getSamplerParameteriv(sampler, pname, params);
+}
+
+void Context::getSamplerParameterIivRobust(GLuint sampler,
+                                           GLenum pname,
+                                           GLsizei bufSize,
+                                           GLsizei *length,
+                                           GLint *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getSamplerParameterIuivRobust(GLuint sampler,
+                                            GLenum pname,
+                                            GLsizei bufSize,
+                                            GLsizei *length,
+                                            GLuint *params)
+{
+    UNIMPLEMENTED();
+}
+
 void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
 {
     const Sampler *samplerObject =
         mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
     QuerySamplerParameterfv(samplerObject, pname, params);
     mGLState.setObjectDirty(GL_SAMPLER);
 }
 
+void Context::getSamplerParameterfvRobust(GLuint sampler,
+                                          GLenum pname,
+                                          GLsizei bufSize,
+                                          GLsizei *length,
+                                          GLfloat *params)
+{
+    getSamplerParameterfv(sampler, pname, params);
+}
+
 void Context::programParameteri(GLuint program, GLenum pname, GLint value)
 {
     gl::Program *programObject = getProgram(program);
     SetProgramParameteri(programObject, pname, value);
 }
 
 void Context::initRendererString()
 {
@@ -2623,17 +2934,20 @@ void Context::requestExtension(const cha
     // Release the shader compiler so it will be re-created with the requested extensions enabled.
     releaseShaderCompiler();
 
     // Invalidate all textures and framebuffer. Some extensions make new formats renderable or
     // sampleable.
     mState.mTextures->signalAllTexturesDirty(this);
     for (auto &zeroTexture : mZeroTextures)
     {
-        zeroTexture.second->signalDirty(this, InitState::Initialized);
+        if (zeroTexture.get() != nullptr)
+        {
+            zeroTexture->signalDirty(this, InitState::Initialized);
+        }
     }
 
     mState.mFramebuffers->invalidateFramebufferComplenessCache();
 }
 
 size_t Context::getRequestableExtensionStringCount() const
 {
     return mRequestableExtensionStrings.size();
@@ -2659,16 +2973,27 @@ bool Context::hasActiveTransformFeedback
     }
     return false;
 }
 
 void Context::initCaps(const egl::DisplayExtensions &displayExtensions, bool robustResourceInit)
 {
     mCaps = mImplementation->getNativeCaps();
 
+    // GLES1 emulation: Initialize caps (Table 6.20 / 6.22 in the ES 1.1 spec)
+    if (getClientVersion() < Version(2, 0))
+    {
+        mCaps.maxMultitextureUnits          = 4;
+        mCaps.maxClipPlanes                 = 6;
+        mCaps.maxLights                     = 8;
+        mCaps.maxModelviewMatrixStackDepth  = Caps::GlobalMatrixStackDepth;
+        mCaps.maxProjectionMatrixStackDepth = Caps::GlobalMatrixStackDepth;
+        mCaps.maxTextureMatrixStackDepth    = Caps::GlobalMatrixStackDepth;
+    }
+
     mExtensions = mImplementation->getNativeExtensions();
 
     mLimitations = mImplementation->getNativeLimitations();
 
     if (getClientVersion() < Version(3, 0))
     {
         // Disable ES3+ extensions
         mExtensions.colorBufferFloat      = false;
@@ -2746,18 +3071,19 @@ void Context::initCaps(const egl::Displa
     LimitCap(&mCaps.maxTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES / 2);
 
     mCaps.maxSampleMaskWords = std::min<GLuint>(mCaps.maxSampleMaskWords, MAX_SAMPLE_MASK_WORDS);
 
     // WebGL compatibility
     mExtensions.webglCompatibility = mWebGLContext;
     for (const auto &extensionInfo : GetExtensionInfoMap())
     {
-        // If this context is for WebGL, disable all enableable extensions
-        if (mWebGLContext && extensionInfo.second.Requestable)
+        // If the user has requested that extensions start disabled and they are requestable,
+        // disable them.
+        if (!mExtensionsEnabled && extensionInfo.second.Requestable)
         {
             mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
         }
     }
 
     // Generate texture caps
     updateCaps();
 }
@@ -2886,42 +3212,83 @@ void Context::initWorkarounds()
 
     // Lose the context upon out of memory error if the application is
     // expecting to watch for those events.
     mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
 }
 
 Error Context::prepareForDraw()
 {
-    syncRendererState();
+    ANGLE_TRY(syncDirtyObjects());
 
     if (isRobustResourceInitEnabled())
     {
         ANGLE_TRY(mGLState.clearUnclearedActiveTextures(this));
         ANGLE_TRY(mGLState.getDrawFramebuffer()->ensureDrawAttachmentsInitialized(this));
     }
 
+    ANGLE_TRY(syncDirtyBits());
     return NoError();
 }
 
-void Context::syncRendererState()
-{
-    mGLState.syncDirtyObjects(this);
+Error Context::prepareForClear(GLbitfield mask)
+{
+    ANGLE_TRY(syncDirtyObjects(mClearDirtyObjects));
+    ANGLE_TRY(mGLState.getDrawFramebuffer()->ensureClearAttachmentsInitialized(this, mask));
+    ANGLE_TRY(syncDirtyBits(mClearDirtyBits));
+    return NoError();
+}
+
+Error Context::prepareForClearBuffer(GLenum buffer, GLint drawbuffer)
+{
+    ANGLE_TRY(syncDirtyObjects(mClearDirtyObjects));
+    ANGLE_TRY(mGLState.getDrawFramebuffer()->ensureClearBufferAttachmentsInitialized(this, buffer,
+                                                                                     drawbuffer));
+    ANGLE_TRY(syncDirtyBits(mClearDirtyBits));
+    return NoError();
+}
+
+Error Context::syncState()
+{
+    ANGLE_TRY(syncDirtyObjects());
+    ANGLE_TRY(syncDirtyBits());
+    return NoError();
+}
+
+Error Context::syncState(const State::DirtyBits &bitMask, const State::DirtyObjects &objectMask)
+{
+    ANGLE_TRY(syncDirtyObjects(objectMask));
+    ANGLE_TRY(syncDirtyBits(bitMask));
+    return NoError();
+}
+
+Error Context::syncDirtyBits()
+{
     const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
     mImplementation->syncState(this, dirtyBits);
     mGLState.clearDirtyBits();
-}
-
-void Context::syncRendererState(const State::DirtyBits &bitMask,
-                                const State::DirtyObjects &objectMask)
-{
-    mGLState.syncDirtyObjects(this, objectMask);
+    return NoError();
+}
+
+Error Context::syncDirtyBits(const State::DirtyBits &bitMask)
+{
     const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
     mImplementation->syncState(this, dirtyBits);
     mGLState.clearDirtyBits(dirtyBits);
+    return NoError();
+}
+
+Error Context::syncDirtyObjects()
+{
+    return mGLState.syncDirtyObjects(this);
+}
+
+Error Context::syncDirtyObjects(const State::DirtyObjects &objectMask)
+{
+    return mGLState.syncDirtyObjects(this, objectMask);
 }
 
 void Context::blitFramebuffer(GLint srcX0,
                               GLint srcY0,
                               GLint srcX1,
                               GLint srcY1,
                               GLint dstX0,
                               GLint dstY0,
@@ -2938,186 +3305,218 @@ void Context::blitFramebuffer(GLint srcX
     }
 
     Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
     ASSERT(drawFramebuffer);
 
     Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
     Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
 
-    syncStateForBlit();
+    ANGLE_CONTEXT_TRY(syncStateForBlit());
 
     handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
 }
 
 void Context::clear(GLbitfield mask)
 {
-    syncStateForClear();
-    handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
+    ANGLE_CONTEXT_TRY(prepareForClear(mask));
+    ANGLE_CONTEXT_TRY(mGLState.getDrawFramebuffer()->clear(this, mask));
 }
 
 void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
 {
-    syncStateForClear();
-    handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
+    ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
+    ANGLE_CONTEXT_TRY(
+        mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
 }
 
 void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
 {
-    syncStateForClear();
-    handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
+    ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
+    ANGLE_CONTEXT_TRY(
+        mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
 }
 
 void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
 {
-    syncStateForClear();
-    handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
+    ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
+    ANGLE_CONTEXT_TRY(
+        mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
 }
 
 void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
 {
     Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
     ASSERT(framebufferObject);
 
     // If a buffer is not present, the clear has no effect
     if (framebufferObject->getDepthbuffer() == nullptr &&
         framebufferObject->getStencilbuffer() == nullptr)
     {
         return;
     }
 
-    syncStateForClear();
-    handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
+    ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
+    ANGLE_CONTEXT_TRY(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
 }
 
 void Context::readPixels(GLint x,
                          GLint y,
                          GLsizei width,
                          GLsizei height,
                          GLenum format,
                          GLenum type,
                          void *pixels)
 {
     if (width == 0 || height == 0)
     {
         return;
     }
 
-    syncStateForReadPixels();
+    ANGLE_CONTEXT_TRY(syncStateForReadPixels());
 
     Framebuffer *readFBO = mGLState.getReadFramebuffer();
     ASSERT(readFBO);
 
     Rectangle area(x, y, width, height);
     handleError(readFBO->readPixels(this, area, format, type, pixels));
 }
 
-void Context::copyTexImage2D(GLenum target,
+void Context::readPixelsRobust(GLint x,
+                               GLint y,
+                               GLsizei width,
+                               GLsizei height,
+                               GLenum format,
+                               GLenum type,
+                               GLsizei bufSize,
+                               GLsizei *length,
+                               GLsizei *columns,
+                               GLsizei *rows,
+                               void *pixels)
+{
+    readPixels(x, y, width, height, format, type, pixels);
+}
+
+void Context::readnPixelsRobust(GLint x,
+                                GLint y,
+                                GLsizei width,
+                                GLsizei height,
+                                GLenum format,
+                                GLenum type,
+                                GLsizei bufSize,
+                                GLsizei *length,
+                                GLsizei *columns,
+                                GLsizei *rows,
+                                void *data)
+{
+    readPixels(x, y, width, height, format, type, data);
+}
+
+void Context::copyTexImage2D(TextureTarget target,
                              GLint level,
                              GLenum internalformat,
                              GLint x,
                              GLint y,
                              GLsizei width,
                              GLsizei height,
                              GLint border)
 {
     // Only sync the read FBO
-    mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
+    ANGLE_CONTEXT_TRY(mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER));
 
     Rectangle sourceArea(x, y, width, height);
 
     Framebuffer *framebuffer = mGLState.getReadFramebuffer();
-    Texture *texture =
-        getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+    Texture *texture         = getTargetTexture(TextureTargetToType(target));
     handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
 }
 
-void Context::copyTexSubImage2D(GLenum target,
+void Context::copyTexSubImage2D(TextureTarget target,
                                 GLint level,
                                 GLint xoffset,
                                 GLint yoffset,
                                 GLint x,
                                 GLint y,
                                 GLsizei width,
                                 GLsizei height)
 {
     if (width == 0 || height == 0)
     {
         return;
     }
 
     // Only sync the read FBO
-    mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
+    ANGLE_CONTEXT_TRY(mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER));
 
     Offset destOffset(xoffset, yoffset, 0);
     Rectangle sourceArea(x, y, width, height);
 
     Framebuffer *framebuffer = mGLState.getReadFramebuffer();
-    Texture *texture =
-        getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+    Texture *texture         = getTargetTexture(TextureTargetToType(target));
     handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
 }
 
-void Context::copyTexSubImage3D(GLenum target,
+void Context::copyTexSubImage3D(TextureType target,
                                 GLint level,
                                 GLint xoffset,
                                 GLint yoffset,
                                 GLint zoffset,
                                 GLint x,
                                 GLint y,
                                 GLsizei width,
                                 GLsizei height)
 {
     if (width == 0 || height == 0)
     {
         return;
     }
 
     // Only sync the read FBO
-    mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
+    ANGLE_CONTEXT_TRY(mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER));
 
     Offset destOffset(xoffset, yoffset, zoffset);
     Rectangle sourceArea(x, y, width, height);
 
     Framebuffer *framebuffer = mGLState.getReadFramebuffer();
     Texture *texture         = getTargetTexture(target);
-    handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
+    handleError(texture->copySubImage(this, NonCubeTextureTypeToTarget(target), level, destOffset,
+                                      sourceArea, framebuffer));
 }
 
 void Context::framebufferTexture2D(GLenum target,
                                    GLenum attachment,
-                                   GLenum textarget,
+                                   TextureTarget textarget,
                                    GLuint texture,
                                    GLint level)
 {
     Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
     ASSERT(framebuffer);
 
     if (texture != 0)
     {
         Texture *textureObj = getTexture(texture);
 
         ImageIndex index = ImageIndex::MakeInvalid();
 
-        if (textarget == GL_TEXTURE_2D)
+        if (textarget == TextureTarget::_2D)
         {
             index = ImageIndex::Make2D(level);
         }
-        else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE)
+        else if (textarget == TextureTarget::Rectangle)
         {
             index = ImageIndex::MakeRectangle(level);
         }
-        else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
+        else if (textarget == TextureTarget::_2DMultisample)
         {
             ASSERT(level == 0);
             index = ImageIndex::Make2DMultisample();
         }
         else
         {
-            ASSERT(IsCubeMapTextureTarget(textarget));
+            ASSERT(TextureTargetToType(textarget) == TextureType::CubeMap);
             index = ImageIndex::MakeCube(textarget, level);
         }
 
         framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
     }
     else
     {
         framebuffer->resetAttachment(this, attachment);
@@ -3159,42 +3558,42 @@ void Context::framebufferTextureLayer(GL
     ASSERT(framebuffer);
 
     if (texture != 0)
     {
         Texture *textureObject = getTexture(texture);
 
         ImageIndex index = ImageIndex::MakeInvalid();
 
-        if (textureObject->getTarget() == GL_TEXTURE_3D)
+        if (textureObject->getType() == TextureType::_3D)
         {
             index = ImageIndex::Make3D(level, layer);
         }
         else
         {
-            ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
+            ASSERT(textureObject->getType() == TextureType::_2DArray);
             index = ImageIndex::Make2DArray(level, layer);
         }
 
         framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
     }
     else
     {
         framebuffer->resetAttachment(this, attachment);
     }
 
     mGLState.setObjectDirty(target);
 }
 
-void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target,
-                                                      GLenum attachment,
-                                                      GLuint texture,
-                                                      GLint level,
-                                                      GLint baseViewIndex,
-                                                      GLsizei numViews)
+void Context::framebufferTextureMultiviewLayered(GLenum target,
+                                                 GLenum attachment,
+                                                 GLuint texture,
+                                                 GLint level,
+                                                 GLint baseViewIndex,
+                                                 GLsizei numViews)
 {
     Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
     ASSERT(framebuffer);
 
     if (texture != 0)
     {
         Texture *textureObj = getTexture(texture);
 
@@ -3205,22 +3604,22 @@ void Context::framebufferTextureMultivie
     else
     {
         framebuffer->resetAttachment(this, attachment);
     }
 
     mGLState.setObjectDirty(target);
 }
 
-void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target,
-                                                         GLenum attachment,
-                                                         GLuint texture,
-                                                         GLint level,
-                                                         GLsizei numViews,
-                                                         const GLint *viewportOffsets)
+void Context::framebufferTextureMultiviewSideBySide(GLenum target,
+                                                    GLenum attachment,
+                                                    GLuint texture,
+                                                    GLint level,
+                                                    GLsizei numViews,
+                                                    const GLint *viewportOffsets)
 {
     Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
     ASSERT(framebuffer);
 
     if (texture != 0)
     {
         Texture *textureObj = getTexture(texture);
 
@@ -3249,131 +3648,177 @@ void Context::readBuffer(GLenum mode)
     Framebuffer *readFBO = mGLState.getReadFramebuffer();
     readFBO->setReadBuffer(mode);
     mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
 }
 
 void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
 {
     // Only sync the FBO
-    mGLState.syncDirtyObject(this, target);
+    ANGLE_CONTEXT_TRY(mGLState.syncDirtyObject(this, target));
 
     Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
     ASSERT(framebuffer);
 
     // The specification isn't clear what should be done when the framebuffer isn't complete.
     // We leave it up to the framebuffer implementation to decide what to do.
     handleError(framebuffer->discard(this, numAttachments, attachments));
 }
 
 void Context::invalidateFramebuffer(GLenum target,
                                     GLsizei numAttachments,
                                     const GLenum *attachments)
 {
     // Only sync the FBO
-    mGLState.syncDirtyObject(this, target);
+    ANGLE_CONTEXT_TRY(mGLState.syncDirtyObject(this, target));
 
     Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
     ASSERT(framebuffer);
 
-    if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
+    bool complete = false;
+    ANGLE_CONTEXT_TRY(framebuffer->isComplete(this, &complete));
+    if (!complete)
     {
         return;
     }
 
     handleError(framebuffer->invalidate(this, numAttachments, attachments));
 }
 
 void Context::invalidateSubFramebuffer(GLenum target,
                                        GLsizei numAttachments,
                                        const GLenum *attachments,
                                        GLint x,
                                        GLint y,
                                        GLsizei width,
                                        GLsizei height)
 {
     // Only sync the FBO
-    mGLState.syncDirtyObject(this, target);
+    ANGLE_CONTEXT_TRY(mGLState.syncDirtyObject(this, target));
 
     Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
     ASSERT(framebuffer);
 
-    if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
+    bool complete = false;
+    ANGLE_CONTEXT_TRY(framebuffer->isComplete(this, &complete));
+    if (!complete)
     {
         return;
     }
 
     Rectangle area(x, y, width, height);
     handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
 }
 
-void Context::texImage2D(GLenum target,
+void Context::texImage2D(TextureTarget target,
                          GLint level,
                          GLint internalformat,
                          GLsizei width,
                          GLsizei height,
                          GLint border,
                          GLenum format,
                          GLenum type,
                          const void *pixels)
 {
-    syncStateForTexImage();
+    ANGLE_CONTEXT_TRY(syncStateForTexImage());
 
     Extents size(width, height, 1);
-    Texture *texture =
-        getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+    Texture *texture = getTargetTexture(TextureTargetToType(target));
     handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
                                   size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
 }
 
-void Context::texImage3D(GLenum target,
+void Context::texImage2DRobust(TextureTarget target,
+                               GLint level,
+                               GLint internalformat,
+                               GLsizei width,
+                               GLsizei height,
+                               GLint border,
+                               GLenum format,
+                               GLenum type,
+                               GLsizei bufSize,
+                               const void *pixels)
+{
+    texImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+}
+
+void Context::texImage3D(TextureType target,
                          GLint level,
                          GLint internalformat,
                          GLsizei width,
                          GLsizei height,
                          GLsizei depth,
                          GLint border,
                          GLenum format,
                          GLenum type,
                          const void *pixels)
 {
-    syncStateForTexImage();
+    ANGLE_CONTEXT_TRY(syncStateForTexImage());
 
     Extents size(width, height, depth);
     Texture *texture = getTargetTexture(target);
-    handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
-                                  size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
-}
-
-void Context::texSubImage2D(GLenum target,
+    handleError(texture->setImage(this, mGLState.getUnpackState(),
+                                  NonCubeTextureTypeToTarget(target), level, internalformat, size,
+                                  format, type, reinterpret_cast<const uint8_t *>(pixels)));
+}
+
+void Context::texImage3DRobust(TextureType target,
+                               GLint level,
+                               GLint internalformat,
+                               GLsizei width,
+                               GLsizei height,
+                               GLsizei depth,
+                               GLint border,
+                               GLenum format,
+                               GLenum type,
+                               GLsizei bufSize,
+                               const void *pixels)
+{
+    texImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
+void Context::texSubImage2D(TextureTarget target,
                             GLint level,
                             GLint xoffset,
                             GLint yoffset,
                             GLsizei width,
                             GLsizei height,
                             GLenum format,
                             GLenum type,
                             const void *pixels)
 {
     // Zero sized uploads are valid but no-ops
     if (width == 0 || height == 0)
     {
         return;
     }
 
-    syncStateForTexImage();
+    ANGLE_CONTEXT_TRY(syncStateForTexImage());
 
     Box area(xoffset, yoffset, 0, width, height, 1);
-    Texture *texture =
-        getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+    Texture *texture = getTargetTexture(TextureTargetToType(target));
     handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
                                      type, reinterpret_cast<const uint8_t *>(pixels)));
 }
 
-void Context::texSubImage3D(GLenum target,
+void Context::texSubImage2DRobust(TextureTarget target,
+                                  GLint level,
+                                  GLint xoffset,
+                                  GLint yoffset,
+                                  GLsizei width,
+                                  GLsizei height,
+                                  GLenum format,
+                                  GLenum type,
+                                  GLsizei bufSize,
+                                  const void *pixels)
+{
+    texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void Context::texSubImage3D(TextureType target,
                             GLint level,
                             GLint xoffset,
                             GLint yoffset,
                             GLint zoffset,
                             GLsizei width,
                             GLsizei height,
                             GLsizei depth,
                             GLenum format,
@@ -3381,83 +3826,142 @@ void Context::texSubImage3D(GLenum targe
                             const void *pixels)
 {
     // Zero sized uploads are valid but no-ops
     if (width == 0 || height == 0 || depth == 0)
     {
         return;
     }
 
-    syncStateForTexImage();
+    ANGLE_CONTEXT_TRY(syncStateForTexImage());
 
     Box area(xoffset, yoffset, zoffset, width, height, depth);
     Texture *texture = getTargetTexture(target);
-    handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
-                                     type, reinterpret_cast<const uint8_t *>(pixels)));
-}
-
-void Context::compressedTexImage2D(GLenum target,
+    handleError(texture->setSubImage(this, mGLState.getUnpackState(),
+                                     NonCubeTextureTypeToTarget(target), level, area, format, type,
+                                     reinterpret_cast<const uint8_t *>(pixels)));
+}
+
+void Context::texSubImage3DRobust(TextureType target,
+                                  GLint level,
+                                  GLint xoffset,
+                                  GLint yoffset,
+                                  GLint zoffset,
+                                  GLsizei width,
+                                  GLsizei height,
+                                  GLsizei depth,
+                                  GLenum format,
+                                  GLenum type,
+                                  GLsizei bufSize,
+                                  const void *pixels)
+{
+    texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type,
+                  pixels);
+}
+
+void Context::compressedTexImage2D(TextureTarget target,
                                    GLint level,
                                    GLenum internalformat,
                                    GLsizei width,
                                    GLsizei height,
                                    GLint border,
                                    GLsizei imageSize,
                                    const void *data)
 {
-    syncStateForTexImage();
+    ANGLE_CONTEXT_TRY(syncStateForTexImage());
 
     Extents size(width, height, 1);
-    Texture *texture =
-        getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+    Texture *texture = getTargetTexture(TextureTargetToType(target));
     handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
                                             internalformat, size, imageSize,
                                             reinterpret_cast<const uint8_t *>(data)));
 }
 
-void Context::compressedTexImage3D(GLenum target,
+void Context::compressedTexImage2DRobust(TextureTarget target,
+                                         GLint level,
+                                         GLenum internalformat,
+                                         GLsizei width,
+                                         GLsizei height,
+                                         GLint border,
+                                         GLsizei imageSize,
+                                         GLsizei dataSize,
+                                         const GLvoid *data)
+{
+    compressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+}
+
+void Context::compressedTexImage3D(TextureType target,
                                    GLint level,
                                    GLenum internalformat,
                                    GLsizei width,
                                    GLsizei height,
                                    GLsizei depth,
                                    GLint border,
                                    GLsizei imageSize,
                                    const void *data)
 {
-    syncStateForTexImage();
+    ANGLE_CONTEXT_TRY(syncStateForTexImage());
 
     Extents size(width, height, depth);
     Texture *texture = getTargetTexture(target);
-    handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
-                                            internalformat, size, imageSize,
-                                            reinterpret_cast<const uint8_t *>(data)));
-}
-
-void Context::compressedTexSubImage2D(GLenum target,
+    handleError(texture->setCompressedImage(
+        this, mGLState.getUnpackState(), NonCubeTextureTypeToTarget(target), level, internalformat,
+        size, imageSize, reinterpret_cast<const uint8_t *>(data)));
+}
+
+void Context::compressedTexImage3DRobust(TextureType target,
+                                         GLint level,
+                                         GLenum internalformat,
+                                         GLsizei width,
+                                         GLsizei height,
+                                         GLsizei depth,
+                                         GLint border,
+                                         GLsizei imageSize,
+                                         GLsizei dataSize,
+                                         const GLvoid *data)
+{
+    compressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize,
+                         data);
+}
+
+void Context::compressedTexSubImage2D(TextureTarget target,
                                       GLint level,
                                       GLint xoffset,
                                       GLint yoffset,
                                       GLsizei width,
                                       GLsizei height,
                                       GLenum format,
                                       GLsizei imageSize,
                                       const void *data)
 {
-    syncStateForTexImage();
+    ANGLE_CONTEXT_TRY(syncStateForTexImage());
 
     Box area(xoffset, yoffset, 0, width, height, 1);
-    Texture *texture =
-        getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+    Texture *texture = getTargetTexture(TextureTargetToType(target));
     handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
                                                format, imageSize,
                                                reinterpret_cast<const uint8_t *>(data)));
 }
 
-void Context::compressedTexSubImage3D(GLenum target,
+void Context::compressedTexSubImage2DRobust(TextureTarget target,
+                                            GLint level,
+                                            GLint xoffset,
+                                            GLint yoffset,
+                                            GLsizei width,
+                                            GLsizei height,
+                                            GLenum format,
+                                            GLsizei imageSize,
+                                            GLsizei dataSize,
+                                            const GLvoid *data)
+{
+    compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize,
+                            data);
+}
+
+void Context::compressedTexSubImage3D(TextureType target,
                                       GLint level,
                                       GLint xoffset,
                                       GLint yoffset,
                                       GLint zoffset,
                                       GLsizei width,
                                       GLsizei height,
                                       GLsizei depth,
                                       GLenum format,
@@ -3465,55 +3969,72 @@ void Context::compressedTexSubImage3D(GL
                                       const void *data)
 {
     // Zero sized uploads are valid but no-ops
     if (width == 0 || height == 0)
     {
         return;
     }
 
-    syncStateForTexImage();
+    ANGLE_CONTEXT_TRY(syncStateForTexImage());
 
     Box area(xoffset, yoffset, zoffset, width, height, depth);
     Texture *texture = getTargetTexture(target);
-    handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
-                                               format, imageSize,
-                                               reinterpret_cast<const uint8_t *>(data)));
-}
-
-void Context::generateMipmap(GLenum target)
+    handleError(texture->setCompressedSubImage(
+        this, mGLState.getUnpackState(), NonCubeTextureTypeToTarget(target), level, area, format,
+        imageSize, reinterpret_cast<const uint8_t *>(data)));
+}
+
+void Context::compressedTexSubImage3DRobust(TextureType target,
+                                            GLint level,
+                                            GLint xoffset,
+                                            GLint yoffset,
+                                            GLint zoffset,
+                                            GLsizei width,
+                                            GLsizei height,
+                                            GLsizei depth,
+                                            GLenum format,
+                                            GLsizei imageSize,
+                                            GLsizei dataSize,
+                                            const GLvoid *data)
+{
+    compressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format,
+                            imageSize, data);
+}
+
+void Context::generateMipmap(TextureType target)
 {
     Texture *texture = getTargetTexture(target);
     handleError(texture->generateMipmap(this));
 }
 
 void Context::copyTexture(GLuint sourceId,
                           GLint sourceLevel,
-                          GLenum destTarget,
+                          TextureTarget destTarget,
                           GLuint destId,
                           GLint destLevel,
                           GLint internalFormat,
                           GLenum destType,
                           GLboolean unpackFlipY,
                           GLboolean unpackPremultiplyAlpha,
                           GLboolean unpackUnmultiplyAlpha)
 {
-    syncStateForTexImage();
+    ANGLE_CONTEXT_TRY(syncStateForTexImage());
 
     gl::Texture *sourceTexture = getTexture(sourceId);
     gl::Texture *destTexture   = getTexture(destId);
     handleError(destTexture->copyTexture(this, destTarget, destLevel, internalFormat, destType,
                                          sourceLevel, ConvertToBool(unpackFlipY),
                                          ConvertToBool(unpackPremultiplyAlpha),
                                          ConvertToBool(unpackUnmultiplyAlpha), sourceTexture));
 }
 
 void Context::copySubTexture(GLuint sourceId,
                              GLint sourceLevel,
-                             GLenum destTarget,
+                             TextureTarget destTarget,
                              GLuint destId,
                              GLint destLevel,
                              GLint xoffset,
                              GLint yoffset,
                              GLint x,
                              GLint y,
                              GLsizei width,
                              GLsizei height,
@@ -3522,45 +4043,54 @@ void Context::copySubTexture(GLuint sour
                              GLboolean unpackUnmultiplyAlpha)
 {
     // Zero sized copies are valid but no-ops
     if (width == 0 || height == 0)
     {
         return;
     }
 
-    syncStateForTexImage();
+    ANGLE_CONTEXT_TRY(syncStateForTexImage());
 
     gl::Texture *sourceTexture = getTexture(sourceId);
     gl::Texture *destTexture   = getTexture(destId);
     Offset offset(xoffset, yoffset, 0);
     Rectangle area(x, y, width, height);
     handleError(destTexture->copySubTexture(this, destTarget, destLevel, offset, sourceLevel, area,
                                             ConvertToBool(unpackFlipY),
                                             ConvertToBool(unpackPremultiplyAlpha),
                                             ConvertToBool(unpackUnmultiplyAlpha), sourceTexture));
 }
 
 void Context::compressedCopyTexture(GLuint sourceId, GLuint destId)
 {
-    syncStateForTexImage();
+    ANGLE_CONTEXT_TRY(syncStateForTexImage());
 
     gl::Texture *sourceTexture = getTexture(sourceId);
     gl::Texture *destTexture   = getTexture(destId);
     handleError(destTexture->copyCompressedTexture(this, sourceTexture));
 }
 
 void Context::getBufferPointerv(BufferBinding target, GLenum pname, void **params)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     ASSERT(buffer);
 
     QueryBufferPointerv(buffer, pname, params);
 }
 
+void Context::getBufferPointervRobust(BufferBinding target,
+                                      GLenum pname,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      void **params)
+{
+    getBufferPointerv(target, pname, params);
+}
+
 void *Context::mapBuffer(BufferBinding target, GLenum access)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     ASSERT(buffer);
 
     Error error = buffer->map(this, access);
     if (error.isError())
     {
@@ -3607,34 +4137,29 @@ void *Context::mapBufferRange(BufferBind
 
 void Context::flushMappedBufferRange(BufferBinding /*target*/,
                                      GLintptr /*offset*/,
                                      GLsizeiptr /*length*/)
 {
     // We do not currently support a non-trivial implementation of FlushMappedBufferRange
 }
 
-void Context::syncStateForReadPixels()
-{
-    syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
-}
-
-void Context::syncStateForTexImage()
-{
-    syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
-}
-
-void Context::syncStateForClear()
-{
-    syncRendererState(mClearDirtyBits, mClearDirtyObjects);
-}
-
-void Context::syncStateForBlit()
-{
-    syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
+Error Context::syncStateForReadPixels()
+{
+    return syncState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
+}
+
+Error Context::syncStateForTexImage()
+{
+    return syncState(mTexImageDirtyBits, mTexImageDirtyObjects);
+}
+
+Error Context::syncStateForBlit()
+{
+    return syncState(mBlitDirtyBits, mBlitDirtyObjects);
 }
 
 void Context::activeShaderProgram(GLuint pipeline, GLuint program)
 {
     UNIMPLEMENTED();
 }
 
 void Context::activeTexture(GLenum texture)
@@ -4004,49 +4529,94 @@ void Context::getVertexAttribiv(GLuint i
 {
     const VertexAttribCurrentValueData &currentValues =
         getGLState().getVertexAttribCurrentValue(index);
     const VertexArray *vao = getGLState().getVertexArray();
     QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
                         currentValues, pname, params);
 }
 
+void Context::getVertexAttribivRobust(GLuint index,
+                                      GLenum pname,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      GLint *params)
+{
+    getVertexAttribiv(index, pname, params);
+}
+
 void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
 {
     const VertexAttribCurrentValueData &currentValues =
         getGLState().getVertexAttribCurrentValue(index);
     const VertexArray *vao = getGLState().getVertexArray();
     QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
                         currentValues, pname, params);
 }
 
+void Context::getVertexAttribfvRobust(GLuint index,
+                                      GLenum pname,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      GLfloat *params)
+{
+    getVertexAttribfv(index, pname, params);
+}
+
 void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
 {
     const VertexAttribCurrentValueData &currentValues =
         getGLState().getVertexAttribCurrentValue(index);
     const VertexArray *vao = getGLState().getVertexArray();
     QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
                          currentValues, pname, params);
 }
 
+void Context::getVertexAttribIivRobust(GLuint index,
+                                       GLenum pname,
+                                       GLsizei bufSize,
+                                       GLsizei *length,
+                                       GLint *params)
+{
+    getVertexAttribIiv(index, pname, params);
+}
+
 void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
 {
     const VertexAttribCurrentValueData &currentValues =
         getGLState().getVertexAttribCurrentValue(index);
     const VertexArray *vao = getGLState().getVertexArray();
     QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
                           currentValues, pname, params);
 }
 
+void Context::getVertexAttribIuivRobust(GLuint index,
+                                        GLenum pname,
+                                        GLsizei bufSize,
+                                        GLsizei *length,
+                                        GLuint *params)
+{
+    getVertexAttribIuiv(index, pname, params);
+}
+
 void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
 {
     const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
     QueryVertexAttribPointerv(attrib, pname, pointer);
 }
 
+void Context::getVertexAttribPointervRobust(GLuint index,
+                                            GLenum pname,
+                                            GLsizei bufSize,
+                                            GLsizei *length,
+                                            void **pointer)
+{
+    getVertexAttribPointerv(index, pname, pointer);
+}
+
 void Context::debugMessageControl(GLenum source,
                                   GLenum type,
                                   GLenum severity,
                                   GLsizei count,
                                   const GLuint *ids,
                                   GLboolean enabled)
 {
     std::vector<GLuint> idVector(ids, ids + count);
@@ -4195,46 +4765,55 @@ void Context::bindFramebuffer(GLenum tar
 void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
 {
     ASSERT(target == GL_RENDERBUFFER);
     Renderbuffer *object =
         mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
     mGLState.setRenderbufferBinding(this, object);
 }
 
-void Context::texStorage2DMultisample(GLenum target,
+void Context::texStorage2DMultisample(TextureType target,
                                       GLsizei samples,
                                       GLenum internalformat,
                                       GLsizei width,
                                       GLsizei height,
                                       GLboolean fixedsamplelocations)
 {
     Extents size(width, height, 1);
     Texture *texture = getTargetTexture(target);
     handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
                                                ConvertToBool(fixedsamplelocations)));
 }
 
 void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
 {
     // According to spec 3.1 Table 20.49: Framebuffer Dependent Values,
     // the sample position should be queried by DRAW_FRAMEBUFFER.
-    mGLState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER);
+    ANGLE_CONTEXT_TRY(mGLState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER));
     const Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
 
     switch (pname)
     {
         case GL_SAMPLE_POSITION:
             handleError(framebuffer->getSamplePosition(index, val));
             break;
         default:
             UNREACHABLE();
     }
 }
 
+void Context::getMultisamplefvRobust(GLenum pname,
+                                     GLuint index,
+                                     GLsizei bufSize,
+                                     GLsizei *length,
+                                     GLfloat *val)
+{
+    UNIMPLEMENTED();
+}
+
 void Context::renderbufferStorage(GLenum target,
                                   GLenum internalformat,
                                   GLsizei width,
                                   GLsizei height)
 {
     // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
     GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
 
@@ -4263,16 +4842,25 @@ void Context::getSynciv(GLsync sync, GLe
 }
 
 void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
 {
     Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
     QueryFramebufferParameteriv(framebuffer, pname, params);
 }
 
+void Context::getFramebufferParameterivRobust(GLenum target,
+                                              GLenum pname,
+                                              GLsizei bufSize,
+                                              GLsizei *length,
+                                              GLint *params)
+{
+    UNIMPLEMENTED();
+}
+
 void Context::framebufferParameteri(GLenum target, GLenum pname, GLint param)
 {
     Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
     SetFramebufferParameteri(framebuffer, pname, param);
 }
 
 Error Context::getScratchBuffer(size_t requstedSizeBytes,
                                 angle::MemoryBuffer **scratchBufferOut) const
@@ -4291,17 +4879,17 @@ Error Context::getZeroFilledBuffer(size_
     {
         return OutOfMemory() << "Failed to allocate internal buffer.";
     }
     return NoError();
 }
 
 Error Context::prepareForDispatch()
 {
-    syncRendererState(mComputeDirtyBits, mComputeDirtyObjects);
+    ANGLE_TRY(syncState(mComputeDirtyBits, mComputeDirtyObjects));
 
     if (isRobustResourceInitEnabled())
     {
         ANGLE_TRY(mGLState.clearUnclearedActiveTextures(this));
     }
 
     return NoError();
 }
@@ -4318,28 +4906,28 @@ void Context::dispatchCompute(GLuint num
 }
 
 void Context::dispatchComputeIndirect(GLintptr indirect)
 {
     ANGLE_CONTEXT_TRY(prepareForDispatch());
     handleError(mImplementation->dispatchComputeIndirect(this, indirect));
 }
 
-void Context::texStorage2D(GLenum target,
+void Context::texStorage2D(TextureType target,
                            GLsizei levels,
                            GLenum internalFormat,
                            GLsizei width,
                            GLsizei height)
 {
     Extents size(width, height, 1);
     Texture *texture = getTargetTexture(target);
     handleError(texture->setStorage(this, target, levels, internalFormat, size));
 }
 
-void Context::texStorage3D(GLenum target,
+void Context::texStorage3D(TextureType target,
                            GLsizei levels,
                            GLenum internalFormat,
                            GLsizei width,
                            GLsizei height,
                            GLsizei depth)
 {
     Extents size(width, height, depth);
     Texture *texture = getTargetTexture(target);
@@ -4356,17 +4944,24 @@ void Context::memoryBarrierByRegion(GLbi
     handleError(mImplementation->memoryBarrierByRegion(this, barriers));
 }
 
 GLenum Context::checkFramebufferStatus(GLenum target)
 {
     Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
     ASSERT(framebuffer);
 
-    return framebuffer->checkStatus(this);
+    GLenum status = GL_NONE;
+    Error err     = framebuffer->checkStatus(this, &status);
+    if (err.isError())
+    {
+        handleError(err);
+        return 0;
+    }
+    return status;
 }
 
 void Context::compileShader(GLuint shader)
 {
     Shader *shaderObject = GetValidShader(this, shader);
     if (!shaderObject)
     {
         return;
@@ -4506,55 +5101,79 @@ void Context::getBooleanv(GLenum pname, 
         getBooleanvImpl(pname, params);
     }
     else
     {
         CastStateValues(this, nativeType, pname, numParams, params);
     }
 }
 
+void Context::getBooleanvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *params)
+{
+    getBooleanv(pname, params);
+}
+
 void Context::getFloatv(GLenum pname, GLfloat *params)
 {
     GLenum nativeType;
     unsigned int numParams = 0;
     getQueryParameterInfo(pname, &nativeType, &numParams);
 
     if (nativeType == GL_FLOAT)
     {
         getFloatvImpl(pname, params);
     }
     else
     {
         CastStateValues(this, nativeType, pname, numParams, params);
     }
 }
 
+void Context::getFloatvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params)
+{
+    getFloatv(pname, params);
+}
+
 void Context::getIntegerv(GLenum pname, GLint *params)
 {
     GLenum nativeType;
     unsigned int numParams = 0;
     getQueryParameterInfo(pname, &nativeType, &numParams);
 
     if (nativeType == GL_INT)
     {
         getIntegervImpl(pname, params);
     }
     else
     {
         CastStateValues(this, nativeType, pname, numParams, params);
     }
 }
 
+void Context::getIntegervRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data)
+{
+    getIntegerv(pname, data);
+}
+
 void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
 {
     Program *programObject = getProgram(program);
     ASSERT(programObject);
     QueryProgramiv(this, programObject, pname, params);
 }
 
+void Context::getProgramivRobust(GLuint program,
+                                 GLenum pname,
+                                 GLsizei bufSize,
+                                 GLsizei *length,
+                                 GLint *params)
+{
+    getProgramiv(program, pname, params);
+}
+
 void Context::getProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
 {
     UNIMPLEMENTED();
 }
 
 void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
 {
     Program *programObject = getProgram(program);
@@ -4572,16 +5191,25 @@ void Context::getProgramPipelineInfoLog(
 
 void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
 {
     Shader *shaderObject = getShader(shader);
     ASSERT(shaderObject);
     QueryShaderiv(this, shaderObject, pname, params);
 }
 
+void Context::getShaderivRobust(GLuint shader,
+                                GLenum pname,
+                                GLsizei bufSize,
+                                GLsizei *length,
+                                GLint *params)
+{
+    getShaderiv(shader, pname, params);
+}
+
 void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
 {
     Shader *shaderObject = getShader(shader);
     ASSERT(shaderObject);
     shaderObject->getInfoLog(this, bufsize, length, infolog);
 }
 
 void Context::getShaderPrecisionFormat(GLenum shadertype,
@@ -4666,23 +5294,41 @@ void Context::getShaderSource(GLuint sha
 
 void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
 {
     Program *programObject = getProgram(program);
     ASSERT(programObject);
     programObject->getUniformfv(this, location, params);
 }
 
+void Context::getUniformfvRobust(GLuint program,
+                                 GLint location,
+                                 GLsizei bufSize,
+                                 GLsizei *length,
+                                 GLfloat *params)
+{
+    getUniformfv(program, location, params);
+}
+
 void Context::getUniformiv(GLuint program, GLint location, GLint *params)
 {
     Program *programObject = getProgram(program);
     ASSERT(programObject);
     programObject->getUniformiv(this, location, params);
 }
 
+void Context::getUniformivRobust(GLuint program,
+                                 GLint location,
+                                 GLsizei bufSize,
+                                 GLsizei *length,
+                                 GLint *params)
+{
+    getUniformiv(program, location, params);
+}
+
 GLint Context::getUniformLocation(GLuint program, const GLchar *name)
 {
     Program *programObject = getProgram(program);
     ASSERT(programObject);
     return programObject->getUniformLocation(name);
 }
 
 GLboolean Context::isBuffer(GLuint buffer)
@@ -5235,16 +5881,25 @@ void Context::resumeTransformFeedback()
 }
 
 void Context::getUniformuiv(GLuint program, GLint location, GLuint *params)
 {
     const Program *programObject = getProgram(program);
     programObject->getUniformuiv(this, location, params);
 }
 
+void Context::getUniformuivRobust(GLuint program,
+                                  GLint location,
+                                  GLsizei bufSize,
+                                  GLsizei *length,
+                                  GLuint *params)
+{
+    getUniformuiv(program, location, params);
+}
+
 GLint Context::getFragDataLocation(GLuint program, const GLchar *name)
 {
     const Program *programObject = getProgram(program);
     return programObject->getFragDataLocation(name);
 }
 
 void Context::getUniformIndices(GLuint program,
                                 GLsizei uniformCount,
@@ -5292,16 +5947,26 @@ void Context::getActiveUniformBlockiv(GL
                                       GLuint uniformBlockIndex,
                                       GLenum pname,
                                       GLint *params)
 {
     const Program *programObject = getProgram(program);
     QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
 }
 
+void Context::getActiveUniformBlockivRobust(GLuint program,
+                                            GLuint uniformBlockIndex,
+                                            GLenum pname,
+                                            GLsizei bufSize,
+                                            GLsizei *length,
+                                            GLint *params)
+{
+    getActiveUniformBlockiv(program, uniformBlockIndex, pname, params);
+}
+
 void Context::getActiveUniformBlockName(GLuint program,
                                         GLuint uniformBlockIndex,
                                         GLsizei bufSize,
                                         GLsizei *length,
                                         GLchar *uniformBlockName)
 {
     const Program *programObject = getProgram(program);
     programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
@@ -5363,22 +6028,36 @@ void Context::getInteger64v(GLenum pname
         getInteger64vImpl(pname, params);
     }
     else
     {
         CastStateValues(this, nativeType, pname, numParams, params);
     }
 }
 
+void Context::getInteger64vRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data)
+{
+    getInteger64v(pname, data);
+}
+
 void Context::getBufferParameteri64v(BufferBinding target, GLenum pname, GLint64 *params)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     QueryBufferParameteri64v(buffer, pname, params);
 }
 
+void Context::getBufferParameteri64vRobust(BufferBinding target,
+                                           GLenum pname,
+                                           GLsizei bufSize,
+                                           GLsizei *length,
+                                           GLint64 *params)
+{
+    getBufferParameteri64v(target, pname, params);
+}
+
 void Context::genSamplers(GLsizei count, GLuint *samplers)
 {
     for (int i = 0; i < count; i++)
     {
         samplers[i] = mState.mSamplers->createSampler();
     }
 }
 
@@ -5402,16 +6081,26 @@ void Context::getInternalformativ(GLenum
                                   GLenum pname,
                                   GLsizei bufSize,
                                   GLint *params)
 {
     const TextureCaps &formatCaps = mTextureCaps.get(internalformat);
     QueryInternalFormativ(formatCaps, pname, bufSize, params);
 }
 
+void Context::getInternalformativRobust(GLenum target,
+                                        GLenum internalformat,
+                                        GLenum pname,
+                                        GLsizei bufSize,
+                                        GLsizei *length,
+                                        GLint *params)
+{
+    getInternalformativ(target, internalformat, pname, bufSize, params);
+}
+
 void Context::programUniform1i(GLuint program, GLint location, GLint v0)
 {
     programUniform1iv(program, location, 1, &v0);
 }
 
 void Context::programUniform2i(GLuint program, GLint location, GLint v0, GLint v1)
 {
     GLint xy[2] = {v0, v1};
@@ -5680,16 +6369,25 @@ void Context::programUniformMatrix4x3fv(
 
 void Context::onTextureChange(const Texture *texture)
 {
     // Conservatively assume all textures are dirty.
     // TODO(jmadill): More fine-grained update.
     mGLState.setObjectDirty(GL_TEXTURE);
 }
 
+bool Context::isCurrentTransformFeedback(const TransformFeedback *tf) const
+{
+    return mGLState.isCurrentTransformFeedback(tf);
+}
+bool Context::isCurrentVertexArray(const VertexArray *va) const
+{
+    return mGLState.isCurrentVertexArray(va);
+}
+
 void Context::genProgramPipelines(GLsizei count, GLuint *pipelines)
 {
     for (int i = 0; i < count; i++)
     {
         pipelines[i] = createProgramPipeline();
     }
 }
 
@@ -5769,24 +6467,51 @@ void Context::getTranslatedShaderSource(
 void Context::getnUniformfv(GLuint program, GLint location, GLsizei bufSize, GLfloat *params)
 {
     Program *programObject = getProgram(program);
     ASSERT(programObject);
 
     programObject->getUniformfv(this, location, params);
 }
 
+void Context::getnUniformfvRobust(GLuint program,
+                                  GLint location,
+                                  GLsizei bufSize,
+                                  GLsizei *length,
+                                  GLfloat *params)
+{
+    UNIMPLEMENTED();
+}
+
 void Context::getnUniformiv(GLuint program, GLint location, GLsizei bufSize, GLint *params)
 {
     Program *programObject = getProgram(program);
     ASSERT(programObject);
 
     programObject->getUniformiv(this, location, params);
 }
 
+void Context::getnUniformivRobust(GLuint program,
+                                  GLint location,
+                                  GLsizei bufSize,
+                                  GLsizei *length,
+                                  GLint *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getnUniformuivRobust(GLuint program,
+                                   GLint location,
+                                   GLsizei bufSize,
+                                   GLsizei *length,
+                                   GLuint *params)
+{
+    UNIMPLEMENTED();
+}
+
 GLboolean Context::isFenceNV(GLuint fence)
 {
     FenceNV *fenceObject = getFenceNV(fence);
 
     if (fenceObject == nullptr)
     {
         return GL_FALSE;
     }
@@ -5831,17 +6556,17 @@ GLboolean Context::testFenceNV(GLuint fe
     {
         handleError(error);
         return GL_TRUE;
     }
 
     return result;
 }
 
-void Context::eGLImageTargetTexture2D(GLenum target, GLeglImageOES image)
+void Context::eGLImageTargetTexture2D(TextureType target, GLeglImageOES image)
 {
     Texture *texture        = getTargetTexture(target);
     egl::Image *imageObject = reinterpret_cast<egl::Image *>(image);
     handleError(texture->setEGLImageTarget(this, target, imageObject));
 }
 
 void Context::eGLImageTargetRenderbufferStorage(GLenum target, GLeglImageOES image)
 {
@@ -5850,515 +6575,776 @@ void Context::eGLImageTargetRenderbuffer
     handleError(renderbuffer->setStorageEGLImageTarget(this, imageObject));
 }
 
 void Context::texStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)
 {
     UNIMPLEMENTED();
 }
 
-void Context::alphaFunc(GLenum func, GLfloat ref)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::alphaFuncx(GLenum func, GLfixed ref)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::clearColorx(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::clearDepthx(GLfixed depth)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::clientActiveTexture(GLenum texture)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::clipPlanef(GLenum p, const GLfloat *eqn)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::clipPlanex(GLenum plane, const GLfixed *equation)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::colorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::cullFace(GLenum mode)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::depthRangex(GLfixed n, GLfixed f)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::disableClientState(GLenum array)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::enableClientState(GLenum array)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::fogf(GLenum pname, GLfloat param)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::fogfv(GLenum pname, const GLfloat *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::fogx(GLenum pname, GLfixed param)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::fogxv(GLenum pname, const GLfixed *param)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::frustumf(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::frustumx(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::getClipPlanef(GLenum plane, GLfloat *equation)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::getClipPlanex(GLenum plane, GLfixed *equation)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::getFixedv(GLenum pname, GLfixed *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::getLightfv(GLenum light, GLenum pname, GLfloat *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::getLightxv(GLenum light, GLenum pname, GLfixed *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::getMaterialfv(GLenum face, GLenum pname, GLfloat *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::getMaterialxv(GLenum face, GLenum pname, GLfixed *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::getTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::getTexEnviv(GLenum target, GLenum pname, GLint *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::getTexEnvxv(GLenum target, GLenum pname, GLfixed *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::getTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::lightModelf(GLenum pname, GLfloat param)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::lightModelfv(GLenum pname, const GLfloat *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::lightModelx(GLenum pname, GLfixed param)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::lightModelxv(GLenum pname, const GLfixed *param)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::lightf(GLenum light, GLenum pname, GLfloat param)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::lightfv(GLenum light, GLenum pname, const GLfloat *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::lightx(GLenum light, GLenum pname, GLfixed param)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::lightxv(GLenum light, GLenum pname, const GLfixed *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::lineWidthx(GLfixed width)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::loadIdentity()
-{
-    UNIMPLEMENTED();
-}
-
-void Context::loadMatrixf(const GLfloat *m)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::loadMatrixx(const GLfixed *m)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::logicOp(GLenum opcode)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::materialf(GLenum face, GLenum pname, GLfloat param)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::materialfv(GLenum face, GLenum pname, const GLfloat *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::materialx(GLenum face, GLenum pname, GLfixed param)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::materialxv(GLenum face, GLenum pname, const GLfixed *param)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::matrixMode(GLenum mode)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::multMatrixf(const GLfloat *m)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::multMatrixx(const GLfixed *m)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::multiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::multiTexCoord4x(GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::normal3f(GLfloat nx, GLfloat ny, GLfloat nz)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::normal3x(GLfixed nx, GLfixed ny, GLfixed nz)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::normalPointer(GLenum type, GLsizei stride, const void *pointer)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::orthof(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::orthox(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::pointParameterf(GLenum pname, GLfloat param)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::pointParameterfv(GLenum pname, const GLfloat *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::pointParameterx(GLenum pname, GLfixed param)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::pointParameterxv(GLenum pname, const GLfixed *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::pointSize(GLfloat size)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::pointSizex(GLfixed size)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::polygonOffsetx(GLfixed factor, GLfixed units)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::popMatrix()
-{
-    UNIMPLEMENTED();
-}
-
-void Context::pushMatrix()
-{
-    UNIMPLEMENTED();
-}
-
-void Context::rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::sampleCoveragex(GLclampx value, GLboolean invert)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::scalef(GLfloat x, GLfloat y, GLfloat z)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::scalex(GLfixed x, GLfixed y, GLfixed z)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::shadeModel(GLenum mode)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::texCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::texEnvf(GLenum target, GLenum pname, GLfloat param)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::texEnvfv(GLenum target, GLenum pname, const GLfloat *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::texEnvi(GLenum target, GLenum pname, GLint param)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::texEnviv(GLenum target, GLenum pname, const GLint *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::texEnvx(GLenum target, GLenum pname, GLfixed param)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::texEnvxv(GLenum target, GLenum pname, const GLfixed *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::texParameterx(GLenum target, GLenum pname, GLfixed param)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::texParameterxv(GLenum target, GLenum pname, const GLfixed *params)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::translatef(GLfloat x, GLfloat y, GLfloat z)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::translatex(GLfixed x, GLfixed y, GLfixed z)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::vertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::drawTexf(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::drawTexfv(const GLfloat *coords)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::drawTexi(GLint x, GLint y, GLint z, GLint width, GLint height)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::drawTexiv(const GLint *coords)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::drawTexs(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::drawTexsv(const GLshort *coords)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::drawTexx(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::drawTexxv(const GLfixed *coords)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::currentPaletteMatrix(GLuint matrixpaletteindex)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::loadPaletteFromModelViewMatrix()
-{
-    UNIMPLEMENTED();
-}
-
-void Context::matrixIndexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::weightPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
-{
-    UNIMPLEMENTED();
-}
-
-void Context::pointSizePointer(GLenum type, GLsizei stride, const void *pointer)
-{
-    UNIMPLEMENTED();
-}
-
-GLbitfield Context::queryMatrixx(GLfixed *mantissa, GLint *exponent)
-{
-    UNIMPLEMENTED();
-    return 0;
+bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
+{
+    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
+    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
+    // to the fact that it is stored internally as a float, and so would require conversion
+    // if returned from Context::getIntegerv. Since this conversion is already implemented
+    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
+    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
+    // application.
+    switch (pname)
+    {
+        case GL_COMPRESSED_TEXTURE_FORMATS:
+        {
+            *type      = GL_INT;
+            *numParams = static_cast<unsigned int>(getCaps().compressedTextureFormats.size());
+            return true;
+        }
+        case GL_SHADER_BINARY_FORMATS:
+        {
+            *type      = GL_INT;
+            *numParams = static_cast<unsigned int>(getCaps().shaderBinaryFormats.size());
+            return true;
+        }
+
+        case GL_MAX_VERTEX_ATTRIBS:
+        case GL_MAX_VERTEX_UNIFORM_VECTORS:
+        case GL_MAX_VARYING_VECTORS:
+        case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+        case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+        case GL_MAX_TEXTURE_IMAGE_UNITS:
+        case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+        case GL_MAX_RENDERBUFFER_SIZE:
+        case GL_NUM_SHADER_BINARY_FORMATS:
+        case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+        case GL_ARRAY_BUFFER_BINDING:
+        case GL_FRAMEBUFFER_BINDING:
+        case GL_RENDERBUFFER_BINDING:
+        case GL_CURRENT_PROGRAM:
+        case GL_PACK_ALIGNMENT:
+        case GL_UNPACK_ALIGNMENT:
+        case GL_GENERATE_MIPMAP_HINT:
+        case GL_RED_BITS:
+        case GL_GREEN_BITS:
+        case GL_BLUE_BITS:
+        case GL_ALPHA_BITS:
+        case GL_DEPTH_BITS:
+        case GL_STENCIL_BITS:
+        case GL_ELEMENT_ARRAY_BUFFER_BINDING:
+        case GL_CULL_FACE_MODE:
+        case GL_FRONT_FACE:
+        case GL_ACTIVE_TEXTURE:
+        case GL_STENCIL_FUNC:
+        case GL_STENCIL_VALUE_MASK:
+        case GL_STENCIL_REF:
+        case GL_STENCIL_FAIL:
+        case GL_STENCIL_PASS_DEPTH_FAIL:
+        case GL_STENCIL_PASS_DEPTH_PASS:
+        case GL_STENCIL_BACK_FUNC:
+        case GL_STENCIL_BACK_VALUE_MASK:
+        case GL_STENCIL_BACK_REF:
+        case GL_STENCIL_BACK_FAIL:
+        case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+        case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+        case GL_DEPTH_FUNC:
+        case GL_BLEND_SRC_RGB:
+        case GL_BLEND_SRC_ALPHA:
+        case GL_BLEND_DST_RGB:
+        case GL_BLEND_DST_ALPHA:
+        case GL_BLEND_EQUATION_RGB:
+        case GL_BLEND_EQUATION_ALPHA:
+        case GL_STENCIL_WRITEMASK:
+        case GL_STENCIL_BACK_WRITEMASK:
+        case GL_STENCIL_CLEAR_VALUE:
+        case GL_SUBPIXEL_BITS:
+        case GL_MAX_TEXTURE_SIZE:
+        case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+        case GL_SAMPLE_BUFFERS:
+        case GL_SAMPLES:
+        case GL_IMPLEMENTATION_COLOR_READ_TYPE:
+        case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
+        case GL_TEXTURE_BINDING_2D:
+        case GL_TEXTURE_BINDING_CUBE_MAP:
+        case GL_RESET_NOTIFICATION_STRATEGY_EXT:
+        {
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+        }
+        case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
+        {
+            if (!getExtensions().packReverseRowOrder)
+            {
+                return false;
+            }
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+        }
+        case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
+        case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
+        {
+            if (!getExtensions().textureRectangle)
+            {
+                return false;
+            }
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+        }
+        case GL_MAX_DRAW_BUFFERS_EXT:
+        case GL_MAX_COLOR_ATTACHMENTS_EXT:
+        {
+            if ((getClientMajorVersion() < 3) && !getExtensions().drawBuffers)
+            {
+                return false;
+            }
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+        }
+        case GL_MAX_VIEWPORT_DIMS:
+        {
+            *type      = GL_INT;
+            *numParams = 2;
+            return true;
+        }
+        case GL_VIEWPORT:
+        case GL_SCISSOR_BOX:
+        {
+            *type      = GL_INT;
+            *numParams = 4;
+            return true;
+        }
+        case GL_SHADER_COMPILER:
+        case GL_SAMPLE_COVERAGE_INVERT:
+        case GL_DEPTH_WRITEMASK:
+        case GL_CULL_FACE:                 // CULL_FACE through DITHER are natural to IsEnabled,
+        case GL_POLYGON_OFFSET_FILL:       // but can be retrieved through the Get{Type}v queries.
+        case GL_SAMPLE_ALPHA_TO_COVERAGE:  // For this purpose, they are treated here as
+                                           // bool-natural
+        case GL_SAMPLE_COVERAGE:
+        case GL_SCISSOR_TEST:
+        case GL_STENCIL_TEST:
+        case GL_DEPTH_TEST:
+        case GL_BLEND:
+        case GL_DITHER:
+        case GL_CONTEXT_ROBUST_ACCESS_EXT:
+        {
+            *type      = GL_BOOL;
+            *numParams = 1;
+            return true;
+        }
+        case GL_COLOR_WRITEMASK:
+        {
+            *type      = GL_BOOL;
+            *numParams = 4;
+            return true;
+        }
+        case GL_POLYGON_OFFSET_FACTOR:
+        case GL_POLYGON_OFFSET_UNITS:
+        case GL_SAMPLE_COVERAGE_VALUE:
+        case GL_DEPTH_CLEAR_VALUE:
+        case GL_LINE_WIDTH:
+        {
+            *type      = GL_FLOAT;
+            *numParams = 1;
+            return true;
+        }
+        case GL_ALIASED_LINE_WIDTH_RANGE:
+        case GL_ALIASED_POINT_SIZE_RANGE:
+        case GL_DEPTH_RANGE:
+        {
+            *type      = GL_FLOAT;
+            *numParams = 2;
+            return true;
+        }
+        case GL_COLOR_CLEAR_VALUE:
+        case GL_BLEND_COLOR:
+        {
+            *type      = GL_FLOAT;
+            *numParams = 4;
+            return true;
+        }
+        case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+            if (!getExtensions().textureFilterAnisotropic)
+            {
+                return false;
+            }
+            *type      = GL_FLOAT;
+            *numParams = 1;
+            return true;
+        case GL_TIMESTAMP_EXT:
+            if (!getExtensions().disjointTimerQuery)
+            {
+                return false;
+            }
+            *type      = GL_INT_64_ANGLEX;
+            *numParams = 1;
+            return true;
+        case GL_GPU_DISJOINT_EXT:
+            if (!getExtensions().disjointTimerQuery)
+            {
+                return false;
+            }
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+        case GL_COVERAGE_MODULATION_CHROMIUM:
+            if (!getExtensions().framebufferMixedSamples)
+            {
+                return false;
+            }
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+        case GL_TEXTURE_BINDING_EXTERNAL_OES:
+            if (!getExtensions().eglStreamConsumerExternal && !getExtensions().eglImageExternal)
+            {
+                return false;
+            }
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+    }
+
+    if (getExtensions().debug)
+    {
+        switch (pname)
+        {
+            case GL_DEBUG_LOGGED_MESSAGES:
+            case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
+            case GL_DEBUG_GROUP_STACK_DEPTH:
+            case GL_MAX_DEBUG_MESSAGE_LENGTH:
+            case GL_MAX_DEBUG_LOGGED_MESSAGES:
+            case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
+            case GL_MAX_LABEL_LENGTH:
+                *type      = GL_INT;
+                *numParams = 1;
+                return true;
+
+            case GL_DEBUG_OUTPUT_SYNCHRONOUS:
+            case GL_DEBUG_OUTPUT:
+                *type      = GL_BOOL;
+                *numParams = 1;
+                return true;
+        }
+    }
+
+    if (getExtensions().multisampleCompatibility)
+    {
+        switch (pname)
+        {
+            case GL_MULTISAMPLE_EXT:
+            case GL_SAMPLE_ALPHA_TO_ONE_EXT:
+                *type      = GL_BOOL;
+                *numParams = 1;
+                return true;
+        }
+    }
+
+    if (getExtensions().pathRendering)
+    {
+        switch (pname)
+        {
+            case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
+            case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
+                *type      = GL_FLOAT;
+                *numParams = 16;
+                return true;
+        }
+    }
+
+    if (getExtensions().bindGeneratesResource)
+    {
+        switch (pname)
+        {
+            case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
+                *type      = GL_BOOL;
+                *numParams = 1;
+                return true;
+        }
+    }
+
+    if (getExtensions().clientArrays)
+    {
+        switch (pname)
+        {
+            case GL_CLIENT_ARRAYS_ANGLE:
+                *type      = GL_BOOL;
+                *numParams = 1;
+                return true;
+        }
+    }
+
+    if (getExtensions().sRGBWriteControl)
+    {
+        switch (pname)
+        {
+            case GL_FRAMEBUFFER_SRGB_EXT:
+                *type      = GL_BOOL;
+                *numParams = 1;
+                return true;
+        }
+    }
+
+    if (getExtensions().robustResourceInitialization &&
+        pname == GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE)
+    {
+        *type      = GL_BOOL;
+        *numParams = 1;
+        return true;
+    }
+
+    if (getExtensions().programCacheControl && pname == GL_PROGRAM_CACHE_ENABLED_ANGLE)
+    {
+        *type      = GL_BOOL;
+        *numParams = 1;
+        return true;
+    }
+
+    // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
+    switch (pname)
+    {
+        // case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE  // equivalent to FRAMEBUFFER_BINDING
+        case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
+            if ((getClientMajorVersion() < 3) && !getExtensions().framebufferBlit)
+            {
+                return false;
+            }
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+
+        case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
+            if ((getClientMajorVersion() < 3) && !getExtensions().getProgramBinary)
+            {
+                return false;
+            }
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+
+        case GL_PROGRAM_BINARY_FORMATS_OES:
+            if ((getClientMajorVersion() < 3) && !getExtensions().getProgramBinary)
+            {
+                return false;
+            }
+            *type      = GL_INT;
+            *numParams = static_cast<unsigned int>(getCaps().programBinaryFormats.size());
+            return true;
+
+        case GL_PACK_ROW_LENGTH:
+        case GL_PACK_SKIP_ROWS:
+        case GL_PACK_SKIP_PIXELS:
+            if ((getClientMajorVersion() < 3) && !getExtensions().packSubimage)
+            {
+                return false;
+            }
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+        case GL_UNPACK_ROW_LENGTH:
+        case GL_UNPACK_SKIP_ROWS:
+        case GL_UNPACK_SKIP_PIXELS:
+            if ((getClientMajorVersion() < 3) && !getExtensions().unpackSubimage)
+            {
+                return false;
+            }
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+        case GL_VERTEX_ARRAY_BINDING:
+            if ((getClientMajorVersion() < 3) && !getExtensions().vertexArrayObject)
+            {
+                return false;
+            }
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+        case GL_PIXEL_PACK_BUFFER_BINDING:
+        case GL_PIXEL_UNPACK_BUFFER_BINDING:
+            if ((getClientMajorVersion() < 3) && !getExtensions().pixelBufferObject)
+            {
+                return false;
+            }
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+        case GL_MAX_SAMPLES:
+        {
+            static_assert(GL_MAX_SAMPLES_ANGLE == GL_MAX_SAMPLES,
+                          "GL_MAX_SAMPLES_ANGLE not equal to GL_MAX_SAMPLES");
+            if ((getClientMajorVersion() < 3) && !getExtensions().framebufferMultisample)
+            {
+                return false;
+            }
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+
+            case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
+                if ((getClientMajorVersion() < 3) && !getExtensions().standardDerivatives)
+                {
+                    return false;
+                }
+                *type      = GL_INT;
+                *numParams = 1;
+                return true;
+        }
+    }
+
+    if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
+    {
+        if ((getClientVersion() < Version(3, 0)) && !getExtensions().drawBuffers)
+        {
+            return false;
+        }
+        *type      = GL_INT;
+        *numParams = 1;
+        return true;
+    }
+
+    if (getExtensions().multiview && pname == GL_MAX_VIEWS_ANGLE)
+    {
+        *type      = GL_INT;
+        *numParams = 1;
+        return true;
+    }
+
+    if (getClientVersion() < Version(2, 0))
+    {
+        switch (pname)
+        {
+            case GL_ALPHA_TEST_FUNC:
+            case GL_CLIENT_ACTIVE_TEXTURE:
+            case GL_MATRIX_MODE:
+            case GL_MAX_TEXTURE_UNITS:
+            case GL_MAX_MODELVIEW_STACK_DEPTH:
+            case GL_MAX_PROJECTION_STACK_DEPTH:
+            case GL_MAX_TEXTURE_STACK_DEPTH:
+                *type      = GL_INT;
+                *numParams = 1;
+                return true;
+            case GL_ALPHA_TEST_REF:
+                *type      = GL_FLOAT;
+                *numParams = 1;
+                return true;
+            case GL_CURRENT_COLOR:
+            case GL_CURRENT_TEXTURE_COORDS:
+                *type      = GL_FLOAT;
+                *numParams = 4;
+                return true;
+            case GL_CURRENT_NORMAL:
+                *type      = GL_FLOAT;
+                *numParams = 3;
+                return true;
+            case GL_MODELVIEW_MATRIX:
+            case GL_PROJECTION_MATRIX:
+            case GL_TEXTURE_MATRIX:
+                *type      = GL_FLOAT;
+                *numParams = 16;
+                return true;
+        }
+    }
+
+    if (getClientVersion() < Version(3, 0))
+    {
+        return false;
+    }
+
+    // Check for ES3.0+ parameter names
+    switch (pname)
+    {
+        case GL_MAX_UNIFORM_BUFFER_BINDINGS:
+        case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
+        case GL_UNIFORM_BUFFER_BINDING:
+        case GL_TRANSFORM_FEEDBACK_BINDING:
+        case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+        case GL_COPY_READ_BUFFER_BINDING:
+        case GL_COPY_WRITE_BUFFER_BINDING:
+        case GL_SAMPLER_BINDING:
+        case GL_READ_BUFFER:
+        case GL_TEXTURE_BINDING_3D:
+        case GL_TEXTURE_BINDING_2D_ARRAY:
+        case GL_MAX_3D_TEXTURE_SIZE:
+        case GL_MAX_ARRAY_TEXTURE_LAYERS:
+        case GL_MAX_VERTEX_UNIFORM_BLOCKS:
+        case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
+        case GL_MAX_COMBINED_UNIFORM_BLOCKS:
+        case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
+        case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
+        case GL_MAX_VARYING_COMPONENTS:
+        case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
+        case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
+        case GL_MIN_PROGRAM_TEXEL_OFFSET:
+        case GL_MAX_PROGRAM_TEXEL_OFFSET:
+        case GL_NUM_EXTENSIONS:
+        case GL_MAJOR_VERSION:
+        case GL_MINOR_VERSION:
+        case GL_MAX_ELEMENTS_INDICES:
+        case GL_MAX_ELEMENTS_VERTICES:
+        case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
+        case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
+        case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
+        case GL_UNPACK_IMAGE_HEIGHT:
+        case GL_UNPACK_SKIP_IMAGES:
+        {
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+        }
+
+        case GL_MAX_ELEMENT_INDEX:
+        case GL_MAX_UNIFORM_BLOCK_SIZE:
+        case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
+        case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
+        case GL_MAX_SERVER_WAIT_TIMEOUT:
+        {
+            *type      = GL_INT_64_ANGLEX;
+            *numParams = 1;
+            return true;
+        }
+
+        case GL_TRANSFORM_FEEDBACK_ACTIVE:
+        case GL_TRANSFORM_FEEDBACK_PAUSED:
+        case GL_PRIMITIVE_RESTART_FIXED_INDEX:
+        case GL_RASTERIZER_DISCARD:
+        {
+            *type      = GL_BOOL;
+            *numParams = 1;
+            return true;
+        }
+
+        case GL_MAX_TEXTURE_LOD_BIAS:
+        {
+            *type      = GL_FLOAT;
+            *numParams = 1;
+            return true;
+        }
+    }
+
+    if (getExtensions().requestExtension)
+    {
+        switch (pname)
+        {
+            case GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE:
+                *type      = GL_INT;
+                *numParams = 1;
+                return true;
+        }
+    }
+
+    if (getClientVersion() < Version(3, 1))
+    {
+        return false;
+    }
+
+    switch (pname)
+    {
+        case GL_ATOMIC_COUNTER_BUFFER_BINDING:
+        case GL_DRAW_INDIRECT_BUFFER_BINDING:
+        case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
+        case GL_MAX_FRAMEBUFFER_WIDTH:
+        case GL_MAX_FRAMEBUFFER_HEIGHT:
+        case GL_MAX_FRAMEBUFFER_SAMPLES:
+        case GL_MAX_SAMPLE_MASK_WORDS:
+        case GL_MAX_COLOR_TEXTURE_SAMPLES:
+        case GL_MAX_DEPTH_TEXTURE_SAMPLES:
+        case GL_MAX_INTEGER_SAMPLES:
+        case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
+        case GL_MAX_VERTEX_ATTRIB_BINDINGS:
+        case GL_MAX_VERTEX_ATTRIB_STRIDE:
+        case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
+        case GL_MAX_VERTEX_ATOMIC_COUNTERS:
+        case GL_MAX_VERTEX_IMAGE_UNIFORMS:
+        case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
+        case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
+        case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
+        case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
+        case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
+        case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
+        case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
+        case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
+        case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
+        case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
+        case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
+        case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
+        case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
+        case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
+        case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
+        case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
+        case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
+        case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
+        case GL_MAX_UNIFORM_LOCATIONS:
+        case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
+        case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
+        case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
+        case GL_MAX_COMBINED_ATOMIC_COUNTERS:
+        case GL_MAX_IMAGE_UNITS:
+        case GL_MAX_COMBINED_IMAGE_UNIFORMS:
+        case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
+        case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
+        case GL_SHADER_STORAGE_BUFFER_BINDING:
+        case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
+        case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+        case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
+            *type      = GL_INT_64_ANGLEX;
+            *numParams = 1;
+            return true;
+        case GL_SAMPLE_MASK:
+            *type      = GL_BOOL;
+            *numParams = 1;
+            return true;
+    }
+
+    if (getExtensions().geometryShader)
+    {
+        switch (pname)
+        {
+            case GL_MAX_FRAMEBUFFER_LAYERS_EXT:
+            case GL_LAYER_PROVOKING_VERTEX_EXT:
+            case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT:
+            case GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT:
+            case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT:
+            case GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT:
+            case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT:
+            case GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT:
+            case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT:
+            case GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT:
+            case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT:
+            case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT:
+            case GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT:
+            case GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT:
+            case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT:
+                *type      = GL_INT;
+                *numParams = 1;
+                return true;
+        }
+    }
+
+    return false;
+}
+
+bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
+{
+    if (getClientVersion() < Version(3, 0))
+    {
+        return false;
+    }
+
+    switch (target)
+    {
+        case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+        case GL_UNIFORM_BUFFER_BINDING:
+        {
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+        }
+        case GL_TRANSFORM_FEEDBACK_BUFFER_START:
+        case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
+        case GL_UNIFORM_BUFFER_START:
+        case GL_UNIFORM_BUFFER_SIZE:
+        {
+            *type      = GL_INT_64_ANGLEX;
+            *numParams = 1;
+            return true;
+        }
+    }
+
+    if (getClientVersion() < Version(3, 1))
+    {
+        return false;
+    }
+
+    switch (target)
+    {
+        case GL_IMAGE_BINDING_LAYERED:
+        {
+            *type      = GL_BOOL;
+            *numParams = 1;
+            return true;
+        }
+        case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
+        case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
+        case GL_ATOMIC_COUNTER_BUFFER_BINDING:
+        case GL_SHADER_STORAGE_BUFFER_BINDING:
+        case GL_VERTEX_BINDING_BUFFER:
+        case GL_VERTEX_BINDING_DIVISOR:
+        case GL_VERTEX_BINDING_OFFSET:
+        case GL_VERTEX_BINDING_STRIDE:
+        case GL_SAMPLE_MASK_VALUE:
+        case GL_IMAGE_BINDING_NAME:
+        case GL_IMAGE_BINDING_LEVEL:
+        case GL_IMAGE_BINDING_LAYER:
+        case GL_IMAGE_BINDING_ACCESS:
+        case GL_IMAGE_BINDING_FORMAT:
+        {
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+        }
+        case GL_ATOMIC_COUNTER_BUFFER_START:
+        case GL_ATOMIC_COUNTER_BUFFER_SIZE:
+        case GL_SHADER_STORAGE_BUFFER_START:
+        case GL_SHADER_STORAGE_BUFFER_SIZE:
+        {
+            *type      = GL_INT_64_ANGLEX;
+            *numParams = 1;
+            return true;
+        }
+    }
+
+    return false;
+}
+
+Program *Context::getProgram(GLuint handle) const
+{
+    return mState.mShaderPrograms->getProgram(handle);
+}
+
+Shader *Context::getShader(GLuint handle) const
+{
+    return mState.mShaderPrograms->getShader(handle);
+}
+
+bool Context::isTextureGenerated(GLuint texture) const
+{
+    return mState.mTextures->isHandleGenerated(texture);
+}
+
+bool Context::isBufferGenerated(GLuint buffer) const
+{
+    return mState.mBuffers->isHandleGenerated(buffer);
+}
+
+bool Context::isRenderbufferGenerated(GLuint renderbuffer) const
+{
+    return mState.mRenderbuffers->isHandleGenerated(renderbuffer);
+}
+
+bool Context::isFramebufferGenerated(GLuint framebuffer) const
+{
+    return mState.mFramebuffers->isHandleGenerated(framebuffer);
+}
+
+bool Context::isProgramPipelineGenerated(GLuint pipeline) const
+{
+    return mState.mPipelines->isHandleGenerated(pipeline);
+}
+
+bool Context::usingDisplayTextureShareGroup() const
+{
+    return mDisplayTextureShareGroup;
+}
+
+GLenum Context::getConvertedRenderbufferFormat(GLenum internalformat) const
+{
+    return mState.mExtensions.webglCompatibility && mState.mClientVersion.major == 2 &&
+                   internalformat == GL_DEPTH_STENCIL
+               ? GL_DEPTH24_STENCIL8
+               : internalformat;
 }
 
 }  // namespace gl
--- a/gfx/angle/checkout/src/libANGLE/Context.h
+++ b/gfx/angle/checkout/src/libANGLE/Context.h
@@ -14,16 +14,17 @@
 #include <string>
 
 #include "angle_gl.h"
 #include "common/MemoryBuffer.h"
 #include "common/angleutils.h"
 #include "libANGLE/Caps.h"
 #include "libANGLE/Constants.h"
 #include "libANGLE/ContextState.h"
+#include "libANGLE/Context_gles_1_0_autogen.h"
 #include "libANGLE/Error.h"
 #include "libANGLE/HandleAllocator.h"
 #include "libANGLE/PackedGLEnums.h"
 #include "libANGLE/RefCountObject.h"
 #include "libANGLE/ResourceMap.h"
 #include "libANGLE/VertexAttribute.h"
 #include "libANGLE/Workarounds.h"
 #include "libANGLE/angletypes.h"
@@ -56,193 +57,85 @@ class Renderbuffer;
 class Sampler;
 class Shader;
 class Texture;
 class TransformFeedback;
 class VertexArray;
 struct VertexAttribute;
 class ProgramPipeline;
 
-class Context final : public ValidationContext
+class Context final : angle::NonCopyable
 {
   public:
     Context(rx::EGLImplFactory *implFactory,
             const egl::Config *config,
             const Context *shareContext,
             TextureManager *shareTextures,
             MemoryProgramCache *memoryProgramCache,
             const egl::AttributeMap &attribs,
             const egl::DisplayExtensions &displayExtensions);
 
     egl::Error onDestroy(const egl::Display *display);
-    ~Context() override;
+    ~Context();
 
     egl::Error makeCurrent(egl::Display *display, egl::Surface *surface);
     egl::Error releaseSurface(const egl::Display *display);
 
     // These create  and destroy methods are merely pass-throughs to
     // ResourceManager, which owns these object types
     GLuint createBuffer();
-    GLuint createShader(GLenum type);
+    GLuint createShader(ShaderType type);
     GLuint createProgram();
     GLuint createTexture();
     GLuint createRenderbuffer();
-    GLuint createPaths(GLsizei range);
+    GLuint genPaths(GLsizei range);
     GLuint createProgramPipeline();
-    GLuint createShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings);
+    GLuint createShaderProgramv(ShaderType type, GLsizei count, const GLchar *const *strings);
 
     void deleteBuffer(GLuint buffer);
     void deleteShader(GLuint shader);
     void deleteProgram(GLuint program);
     void deleteTexture(GLuint texture);
     void deleteRenderbuffer(GLuint renderbuffer);
     void deletePaths(GLuint first, GLsizei range);
     void deleteProgramPipeline(GLuint pipeline);
 
     // CHROMIUM_path_rendering
-    bool hasPathData(GLuint path) const;
-    bool hasPath(GLuint path) const;
-    void setPathCommands(GLuint path,
-                         GLsizei numCommands,
-                         const GLubyte *commands,
-                         GLsizei numCoords,
-                         GLenum coordType,
-                         const void *coords);
+    bool isPath(GLuint path) const;
+    bool isPathGenerated(GLuint path) const;
+    void pathCommands(GLuint path,
+                      GLsizei numCommands,
+                      const GLubyte *commands,
+                      GLsizei numCoords,
+                      GLenum coordType,
+                      const void *coords);
     void pathParameterf(GLuint path, GLenum pname, GLfloat value);
     void pathParameteri(GLuint path, GLenum pname, GLint value);
     void getPathParameterfv(GLuint path, GLenum pname, GLfloat *value);
     void getPathParameteriv(GLuint path, GLenum pname, GLint *value);
-    void setPathStencilFunc(GLenum func, GLint ref, GLuint mask);
+    void pathStencilFunc(GLenum func, GLint ref, GLuint mask);
 
     // Framebuffers are owned by the Context, so these methods do not pass through
     GLuint createFramebuffer();
     void deleteFramebuffer(GLuint framebuffer);
 
     // NV Fences are owned by the Context.
     void genFencesNV(GLsizei n, GLuint *fences);
     void deleteFencesNV(GLsizei n, const GLuint *fences);
     void finishFenceNV(GLuint fence);
     void getFenceivNV(GLuint fence, GLenum pname, GLint *params);
     GLboolean isFenceNV(GLuint fence);
     void setFenceNV(GLuint fence, GLenum condition);
     GLboolean testFenceNV(GLuint fence);
 
-    // OpenGL ES 1
-    void alphaFunc(GLenum func, GLfloat ref);
-    void alphaFuncx(GLenum func, GLfixed ref);
-    void clearColorx(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
-    void clearDepthx(GLfixed depth);
-    void clientActiveTexture(GLenum texture);
-    void clipPlanef(GLenum p, const GLfloat *eqn);
-    void clipPlanex(GLenum plane, const GLfixed *equation);
-    void color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
-    void color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
-    void color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
-    void colorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer);
-    void cullFace(GLenum mode);
-    void depthRangex(GLfixed n, GLfixed f);
-    void disableClientState(GLenum array);
-    void enableClientState(GLenum array);
-    void fogf(GLenum pname, GLfloat param);
-    void fogfv(GLenum pname, const GLfloat *params);
-    void fogx(GLenum pname, GLfixed param);
-    void fogxv(GLenum pname, const GLfixed *param);
-    void frustumf(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);
-    void frustumx(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f);
-    void getBufferParameteriv(GLenum target, GLenum pname, GLint *params);
-    void getClipPlanef(GLenum plane, GLfloat *equation);
-    void getClipPlanex(GLenum plane, GLfixed *equation);
-    void getFixedv(GLenum pname, GLfixed *params);
-    void getLightfv(GLenum light, GLenum pname, GLfloat *params);
-    void getLightxv(GLenum light, GLenum pname, GLfixed *params);
-    void getMaterialfv(GLenum face, GLenum pname, GLfloat *params);
-    void getMaterialxv(GLenum face, GLenum pname, GLfixed *params);
-    void getTexEnvfv(GLenum target, GLenum pname, GLfloat *params);
-    void getTexEnviv(GLenum target, GLenum pname, GLint *params);
-    void getTexEnvxv(GLenum target, GLenum pname, GLfixed *params);
-    void getTexParameterxv(GLenum target, GLenum pname, GLfixed *params);
-    void lightModelf(GLenum pname, GLfloat param);
-    void lightModelfv(GLenum pname, const GLfloat *params);
-    void lightModelx(GLenum pname, GLfixed param);
-    void lightModelxv(GLenum pname, const GLfixed *param);
-    void lightf(GLenum light, GLenum pname, GLfloat param);
-    void lightfv(GLenum light, GLenum pname, const GLfloat *params);
-    void lightx(GLenum light, GLenum pname, GLfixed param);
-    void lightxv(GLenum light, GLenum pname, const GLfixed *params);
-    void lineWidthx(GLfixed width);
-    void loadIdentity();
-    void loadMatrixf(const GLfloat *m);
-    void loadMatrixx(const GLfixed *m);
-    void logicOp(GLenum opcode);
-    void materialf(GLenum face, GLenum pname, GLfloat param);
-    void materialfv(GLenum face, GLenum pname, const GLfloat *params);
-    void materialx(GLenum face, GLenum pname, GLfixed param);
-    void materialxv(GLenum face, GLenum pname, const GLfixed *param);
-    void matrixMode(GLenum mode);
-    void multMatrixf(const GLfloat *m);
-    void multMatrixx(const GLfixed *m);
-    void multiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
-    void multiTexCoord4x(GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
-    void normal3f(GLfloat nx, GLfloat ny, GLfloat nz);
-    void normal3x(GLfixed nx, GLfixed ny, GLfixed nz);
-    void normalPointer(GLenum type, GLsizei stride, const void *pointer);
-    void orthof(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);
-    void orthox(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f);
-    void pointParameterf(GLenum pname, GLfloat param);
-    void pointParameterfv(GLenum pname, const GLfloat *params);
-    void pointParameterx(GLenum pname, GLfixed param);
-    void pointParameterxv(GLenum pname, const GLfixed *params);
-    void pointSize(GLfloat size);
-    void pointSizex(GLfixed size);
-    void polygonOffsetx(GLfixed factor, GLfixed units);
-    void popMatrix();
-    void pushMatrix();
-    void rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
-    void rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
-    void sampleCoveragex(GLclampx value, GLboolean invert);
-    void scalef(GLfloat x, GLfloat y, GLfloat z);
-    void scalex(GLfixed x, GLfixed y, GLfixed z);
-    void shadeModel(GLenum mode);
-    void texCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer);
-    void texEnvf(GLenum target, GLenum pname, GLfloat param);
-    void texEnvfv(GLenum target, GLenum pname, const GLfloat *params);
-    void texEnvi(GLenum target, GLenum pname, GLint param);
-    void texEnviv(GLenum target, GLenum pname, const GLint *params);
-    void texEnvx(GLenum target, GLenum pname, GLfixed param);
-    void texEnvxv(GLenum target, GLenum pname, const GLfixed *params);
-    void texParameterx(GLenum target, GLenum pname, GLfixed param);
-    void texParameterxv(GLenum target, GLenum pname, const GLfixed *params);
-    void translatef(GLfloat x, GLfloat y, GLfloat z);
-    void translatex(GLfixed x, GLfixed y, GLfixed z);
-    void vertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer);
-
-    // GL_OES_draw_texture
-    void drawTexf(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
-    void drawTexfv(const GLfloat *coords);
-    void drawTexi(GLint x, GLint y, GLint z, GLint width, GLint height);
-    void drawTexiv(const GLint *coords);
-    void drawTexs(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height);
-    void drawTexsv(const GLshort *coords);
-    void drawTexx(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height);
-    void drawTexxv(const GLfixed *coords);
-
-    // GL_OES_matrix_palette
-    void currentPaletteMatrix(GLuint matrixpaletteindex);
-    void loadPaletteFromModelViewMatrix();
-    void matrixIndexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer);
-    void weightPointer(GLint size, GLenum type, GLsizei stride, const void *pointer);
-
-    // GL_OES_point_size_array
-    void pointSizePointer(GLenum type, GLsizei stride, const void *pointer);
-
-    // GL_OES_query_matrix
-    GLbitfield queryMatrixx(GLfixed *mantissa, GLint *exponent);
+    // GLES1 emulation: Interface to entry points
+    ANGLE_GLES1_CONTEXT_API
 
     // OpenGL ES 2+
-    void bindTexture(GLenum target, GLuint handle);
+    void bindTexture(TextureType target, GLuint handle);
     void bindReadFramebuffer(GLuint framebufferHandle);
     void bindDrawFramebuffer(GLuint framebufferHandle);
     void bindVertexArray(GLuint vertexArrayHandle);
     void bindVertexBuffer(GLuint bindingIndex,
                           GLuint bufferHandle,
                           GLintptr offset,
                           GLsizei stride);
     void bindSampler(GLuint textureUnit, GLuint samplerHandle);
@@ -257,47 +150,174 @@ class Context final : public ValidationC
     void useProgramStages(GLuint pipeline, GLbitfield stages, GLuint program);
     void bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle);
     void bindProgramPipeline(GLuint pipelineHandle);
 
     void beginQuery(GLenum target, GLuint query);
     void endQuery(GLenum target);
     void queryCounter(GLuint id, GLenum target);
     void getQueryiv(GLenum target, GLenum pname, GLint *params);
+    void getQueryivRobust(GLenum target,
+                          GLenum pname,
+                          GLsizei bufSize,
+                          GLsizei *length,
+                          GLint *params);
+
     void getQueryObjectiv(GLuint id, GLenum pname, GLint *params);
+    void getQueryObjectivRobust(GLuint id,
+                                GLenum pname,
+                                GLsizei bufSize,
+                                GLsizei *length,
+                                GLint *params);
     void getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params);
+    void getQueryObjectuivRobust(GLuint id,
+                                 GLenum pname,
+                                 GLsizei bufSize,
+                                 GLsizei *length,
+                                 GLuint *params);
     void getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params);
+    void getQueryObjecti64vRobust(GLuint id,
+                                  GLenum pname,
+                                  GLsizei bufSize,
+                                  GLsizei *length,
+                                  GLint64 *params);
     void getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params);
+    void getQueryObjectui64vRobust(GLuint id,
+                                   GLenum pname,
+                                   GLsizei bufSize,
+                                   GLsizei *length,
+                                   GLuint64 *params);
 
     void vertexAttribDivisor(GLuint index, GLuint divisor);
     void vertexBindingDivisor(GLuint bindingIndex, GLuint divisor);
 
     void getBufferParameteriv(BufferBinding target, GLenum pname, GLint *params);
+    void getBufferParameterivRobust(BufferBinding target,
+                                    GLenum pname,
+                                    GLsizei bufSize,
+                                    GLsizei *length,
+                                    GLint *params);
+
     void getFramebufferAttachmentParameteriv(GLenum target,
                                              GLenum attachment,
                                              GLenum pname,
                                              GLint *params);
+    void getFramebufferAttachmentParameterivRobust(GLenum target,
+                                                   GLenum attachment,
+                                                   GLenum pname,
+                                                   GLsizei bufSize,
+                                                   GLsizei *length,
+                                                   GLint *params);
     void getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params);
+    void getRenderbufferParameterivRobust(GLenum target,
+                                          GLenum pname,
+                                          GLsizei bufSize,
+                                          GLsizei *length,
+                                          GLint *params);
 
-    void getTexParameterfv(GLenum target, GLenum pname, GLfloat *params);
-    void getTexParameteriv(GLenum target, GLenum pname, GLint *params);
-    void getTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params);
-    void getTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params);
-    void texParameterf(GLenum target, GLenum pname, GLfloat param);
-    void texParameterfv(GLenum target, GLenum pname, const GLfloat *params);
-    void texParameteri(GLenum target, GLenum pname, GLint param);
-    void texParameteriv(GLenum target, GLenum pname, const GLint *params);
+    void getTexParameterfv(TextureType target, GLenum pname, GLfloat *params);
+    void getTexParameterfvRobust(TextureType target,
+                                 GLenum pname,
+                                 GLsizei bufSize,
+                                 GLsizei *length,
+                                 GLfloat *params);
+    void getTexParameteriv(TextureType target, GLenum pname, GLint *params);
+    void getTexParameterivRobust(TextureType target,
+                                 GLenum pname,
+                                 GLsizei bufSize,
+                                 GLsizei *length,
+                                 GLint *params);
+    void getTexParameterIivRobust(TextureType target,
+                                  GLenum pname,
+                                  GLsizei bufSize,
+                                  GLsizei *length,
+                                  GLint *params);
+    void getTexParameterIuivRobust(TextureType target,
+                                   GLenum pname,
+                                   GLsizei bufSize,
+                                   GLsizei *length,
+                                   GLuint *params);
 
+    void getTexLevelParameteriv(TextureTarget target, GLint level, GLenum pname, GLint *params);
+    void getTexLevelParameterivRobust(TextureTarget target,
+                                      GLint level,
+                                      GLenum pname,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      GLint *params);
+    void getTexLevelParameterfv(TextureTarget target, GLint level, GLenum pname, GLfloat *params);
+    void getTexLevelParameterfvRobust(TextureTarget target,
+                                      GLint level,
+                                      GLenum pname,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      GLfloat *params);
+    void texParameterf(TextureType target, GLenum pname, GLfloat param);
+    void texParameterfv(TextureType target, GLenum pname, const GLfloat *params);
+    void texParameterfvRobust(TextureType target,
+                              GLenum pname,
+                              GLsizei bufSize,
+                              const GLfloat *params);
+    void texParameteri(TextureType target, GLenum pname, GLint param);
+    void texParameteriv(TextureType target, GLenum pname, const GLint *params);
+    void texParameterivRobust(TextureType target,
+                              GLenum pname,
+                              GLsizei bufSize,
+                              const GLint *params);
+    void texParameterIivRobust(TextureType target,
+                               GLenum pname,
+                               GLsizei bufSize,
+                               const GLint *params);
+    void texParameterIuivRobust(TextureType target,
+                                GLenum pname,
+                                GLsizei bufSize,
+                                const GLuint *params);
     void samplerParameteri(GLuint sampler, GLenum pname, GLint param);
     void samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param);
+    void samplerParameterivRobust(GLuint sampler,
+                                  GLenum pname,
+                                  GLsizei bufSize,
+                                  const GLint *param);
+    void samplerParameterIivRobust(GLuint sampler,
+                                   GLenum pname,
+                                   GLsizei bufSize,
+                                   const GLint *param);
+    void samplerParameterIuivRobust(GLuint sampler,
+                                    GLenum pname,
+                                    GLsizei bufSize,
+                                    const GLuint *param);
     void samplerParameterf(GLuint sampler, GLenum pname, GLfloat param);
     void samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param);
+    void samplerParameterfvRobust(GLuint sampler,
+                                  GLenum pname,
+                                  GLsizei bufSize,
+                                  const GLfloat *param);
 
     void getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params);
+    void getSamplerParameterivRobust(GLuint sampler,
+                                     GLenum pname,
+                                     GLsizei bufSize,
+                                     GLsizei *length,
+                                     GLint *params);
+    void getSamplerParameterIivRobust(GLuint sampler,
+                                      GLenum pname,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      GLint *params);
+    void getSamplerParameterIuivRobust(GLuint sampler,
+                                       GLenum pname,
+                                       GLsizei bufSize,
+                                       GLsizei *length,
+                                       GLuint *params);
     void getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params);
+    void getSamplerParameterfvRobust(GLuint sampler,
+                                     GLenum pname,
+                                     GLsizei bufSize,
+                                     GLsizei *length,
+                                     GLfloat *params);
 
     void programParameteri(GLuint program, GLenum pname, GLint value);
 
     GLuint getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name);
     void getProgramResourceName(GLuint program,
                                 GLenum programInterface,
                                 GLuint index,
                                 GLsizei bufSize,
@@ -312,16 +332,22 @@ class Context final : public ValidationC
                               GLsizei bufSize,
                               GLsizei *length,
                               GLint *params);
 
     void getProgramInterfaceiv(GLuint program,
                                GLenum programInterface,
                                GLenum pname,
                                GLint *params);
+    void getProgramInterfaceivRobust(GLuint program,
+                                     GLenum programInterface,
+                                     GLenum pname,
+                                     GLsizei bufSize,
+                                     GLsizei *length,
+                                     GLint *params);
 
     Buffer *getBuffer(GLuint handle) const;
     FenceNV *getFenceNV(GLuint handle);
     Sync *getSync(GLsync handle) const;
     Texture *getTexture(GLuint handle) const;
     Framebuffer *getFramebuffer(GLuint handle) const;
     Renderbuffer *getRenderbuffer(GLuint handle) const;
     VertexArray *getVertexArray(GLuint handle) const;
@@ -335,37 +361,59 @@ class Context final : public ValidationC
     void objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label);
     void getObjectLabel(GLenum identifier,
                         GLuint name,
                         GLsizei bufSize,
                         GLsizei *length,
                         GLchar *label) const;
     void getObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label) const;
 
-    Texture *getTargetTexture(GLenum target) const;
-    Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
+    Texture *getTargetTexture(TextureType type) const;
+    Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;
 
     Compiler *getCompiler() const;
 
     bool isSampler(GLuint samplerName) const;
 
     bool isVertexArrayGenerated(GLuint vertexArray);
     bool isTransformFeedbackGenerated(GLuint vertexArray);
 
     void getBooleanv(GLenum pname, GLboolean *params);
+    void getBooleanvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *params);
     void getBooleanvImpl(GLenum pname, GLboolean *params);
     void getFloatv(GLenum pname, GLfloat *params);
+    void getFloatvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
     void getFloatvImpl(GLenum pname, GLfloat *params);
     void getIntegerv(GLenum pname, GLint *params);
+    void getIntegervRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data);
     void getIntegervImpl(GLenum pname, GLint *params);
     void getInteger64vImpl(GLenum pname, GLint64 *params);
     void getPointerv(GLenum pname, void **params) const;
+    void getPointervRobustANGLERobust(GLenum pname,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      void **params);
     void getBooleani_v(GLenum target, GLuint index, GLboolean *data);
+    void getBooleani_vRobust(GLenum target,
+                             GLuint index,
+                             GLsizei bufSize,
+                             GLsizei *length,
+                             GLboolean *data);
     void getIntegeri_v(GLenum target, GLuint index, GLint *data);
+    void getIntegeri_vRobust(GLenum target,
+                             GLuint index,
+                             GLsizei bufSize,
+                             GLsizei *length,
+                             GLint *data);
     void getInteger64i_v(GLenum target, GLuint index, GLint64 *data);
+    void getInteger64i_vRobust(GLenum target,
+                               GLuint index,
+                               GLsizei bufSize,
+                               GLsizei *length,
+                               GLint64 *data);
 
     void activeShaderProgram(GLuint pipeline, GLuint program);
     void activeTexture(GLenum texture);
     void blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
     void blendEquation(GLenum mode);
     void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
     void blendFunc(GLenum sfactor, GLenum dfactor);
     void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
@@ -420,20 +468,45 @@ class Context final : public ValidationC
                               const void *pointer);
     void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
 
     void vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w);
     void vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
     void vertexAttribI4iv(GLuint index, const GLint *v);
     void vertexAttribI4uiv(GLuint index, const GLuint *v);
     void getVertexAttribiv(GLuint index, GLenum pname, GLint *params);
+    void getVertexAttribivRobust(GLuint index,
+                                 GLenum pname,
+                                 GLsizei bufSize,
+                                 GLsizei *length,
+                                 GLint *params);
     void getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
+    void getVertexAttribfvRobust(GLuint index,
+                                 GLenum pname,
+                                 GLsizei bufSize,
+                                 GLsizei *length,
+                                 GLfloat *params);
     void getVertexAttribIiv(GLuint index, GLenum pname, GLint *params);
+    void getVertexAttribIivRobust(GLuint index,
+                                  GLenum pname,
+                                  GLsizei bufSize,
+                                  GLsizei *length,
+                                  GLint *params);
     void getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params);
+    void getVertexAttribIuivRobust(GLuint index,
+                                   GLenum pname,
+                                   GLsizei bufSize,
+                                   GLsizei *length,
+                                   GLuint *params);
     void getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer);
+    void getVertexAttribPointervRobust(GLuint index,
+                                       GLenum pname,
+                                       GLsizei bufSize,
+                                       GLsizei *length,
+                                       void **pointer);
 
     void debugMessageControl(GLenum source,
                              GLenum type,
                              GLenum severity,
                              GLsizei count,
                              const GLuint *ids,
                              GLboolean enabled);
     void debugMessageInsert(GLenum source,
@@ -491,195 +564,306 @@ class Context final : public ValidationC
 
     void readPixels(GLint x,
                     GLint y,
                     GLsizei width,
                     GLsizei height,
                     GLenum format,
                     GLenum type,
                     void *pixels);
+    void readPixelsRobust(GLint x,
+                          GLint y,
+                          GLsizei width,
+                          GLsizei height,
+                          GLenum format,
+                          GLenum type,
+                          GLsizei bufSize,
+                          GLsizei *length,
+                          GLsizei *columns,
+                          GLsizei *rows,
+                          void *pixels);
+    void readnPixelsRobust(GLint x,
+                           GLint y,
+                           GLsizei width,
+                           GLsizei height,
+                           GLenum format,
+                           GLenum type,
+                           GLsizei bufSize,
+                           GLsizei *length,
+                           GLsizei *columns,
+                           GLsizei *rows,
+                           void *data);
 
-    void copyTexImage2D(GLenum target,
+    void copyTexImage2D(TextureTarget target,
                         GLint level,
                         GLenum internalformat,
                         GLint x,
                         GLint y,
                         GLsizei width,
                         GLsizei height,
                         GLint border);
 
-    void copyTexSubImage2D(GLenum target,
+    void copyTexSubImage2D(TextureTarget target,
                            GLint level,
                            GLint xoffset,
                            GLint yoffset,
                            GLint x,
                            GLint y,
                            GLsizei width,
                            GLsizei height);
 
-    void copyTexSubImage3D(GLenum target,
+    void copyTexSubImage3D(TextureType target,
                            GLint level,
                            GLint xoffset,
                            GLint yoffset,
                            GLint zoffset,
                            GLint x,
                            GLint y,
                            GLsizei width,
                            GLsizei height);
 
     void framebufferTexture2D(GLenum target,
                               GLenum attachment,
-                              GLenum textarget,
+                              TextureTarget textarget,
                               GLuint texture,
                               GLint level);
 
     void framebufferRenderbuffer(GLenum target,
                                  GLenum attachment,
                                  GLenum renderbuffertarget,
                                  GLuint renderbuffer);
 
     void framebufferTextureLayer(GLenum target,
                                  GLenum attachment,
                                  GLuint texture,
                                  GLint level,
                                  GLint layer);
-    void framebufferTextureMultiviewLayeredANGLE(GLenum target,
-                                                 GLenum attachment,
-                                                 GLuint texture,
-                                                 GLint level,
-                                                 GLint baseViewIndex,
-                                                 GLsizei numViews);
-    void framebufferTextureMultiviewSideBySideANGLE(GLenum target,
-                                                    GLenum attachment,
-                                                    GLuint texture,
-                                                    GLint level,
-                                                    GLsizei numViews,
-                                                    const GLint *viewportOffsets);
+    void framebufferTextureMultiviewLayered(GLenum target,
+                                            GLenum attachment,
+                                            GLuint texture,
+                                            GLint level,
+                                            GLint baseViewIndex,
+                                            GLsizei numViews);
+    void framebufferTextureMultiviewSideBySide(GLenum target,
+                                               GLenum attachment,
+                                               GLuint texture,
+                                               GLint level,
+                                               GLsizei numViews,
+                                               const GLint *viewportOffsets);
 
     void drawBuffers(GLsizei n, const GLenum *bufs);
     void readBuffer(GLenum mode);
 
     void discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments);
     void invalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments);
     void invalidateSubFramebuffer(GLenum target,
                                   GLsizei numAttachments,
                                   const GLenum *attachments,
                                   GLint x,
                                   GLint y,
                                   GLsizei width,
                                   GLsizei height);
 
-    void texImage2D(GLenum target,
+    void texImage2D(TextureTarget target,
                     GLint level,
                     GLint internalformat,
                     GLsizei width,
                     GLsizei height,
                     GLint border,
                     GLenum format,
                     GLenum type,
                     const void *pixels);
-    void texImage3D(GLenum target,
+    void texImage2DRobust(TextureTarget target,
+                          GLint level,
+                          GLint internalformat,
+                          GLsizei width,
+                          GLsizei height,
+                          GLint border,
+                          GLenum format,
+                          GLenum type,
+                          GLsizei bufSize,
+                          const void *pixels);
+    void texImage3D(TextureType target,
                     GLint level,
                     GLint internalformat,
                     GLsizei width,
                     GLsizei height,
                     GLsizei depth,
                     GLint border,
                     GLenum format,
                     GLenum type,
                     const void *pixels);
-    void texSubImage2D(GLenum target,
+    void texImage3DRobust(TextureType target,
+                          GLint level,
+                          GLint internalformat,
+                          GLsizei width,
+                          GLsizei height,
+                          GLsizei depth,
+                          GLint border,
+                          GLenum format,
+                          GLenum type,
+                          GLsizei bufSize,
+                          const void *pixels);
+    void texSubImage2D(TextureTarget target,
                        GLint level,
                        GLint xoffset,
                        GLint yoffset,
                        GLsizei width,
                        GLsizei height,
                        GLenum format,
                        GLenum type,
                        const void *pixels);
-    void texSubImage3D(GLenum target,
+    void texSubImage2DRobust(TextureTarget target,
+                             GLint level,
+                             GLint xoffset,
+                             GLint yoffset,
+                             GLsizei width,
+                             GLsizei height,
+                             GLenum format,
+                             GLenum type,
+                             GLsizei bufSize,
+                             const void *pixels);
+    void texSubImage3D(TextureType target,
                        GLint level,
                        GLint xoffset,
                        GLint yoffset,
                        GLint zoffset,
                        GLsizei width,
                        GLsizei height,
                        GLsizei depth,
                        GLenum format,
                        GLenum type,
                        const void *pixels);
-    void compressedTexImage2D(GLenum target,
+    void texSubImage3DRobust(TextureType target,
+                             GLint level,
+                             GLint xoffset,
+                             GLint yoffset,
+                             GLint zoffset,
+                             GLsizei width,
+                             GLsizei height,
+                             GLsizei depth,
+                             GLenum format,
+                             GLenum type,
+                             GLsizei bufSize,
+                             const void *pixels);
+    void compressedTexImage2D(TextureTarget target,
                               GLint level,
                               GLenum internalformat,
                               GLsizei width,
                               GLsizei height,
                               GLint border,
                               GLsizei imageSize,
                               const void *data);
-    void compressedTexImage3D(GLenum target,
+    void compressedTexImage2DRobust(TextureTarget target,
+                                    GLint level,
+                                    GLenum internalformat,
+                                    GLsizei width,
+                                    GLsizei height,
+                                    GLint border,
+                                    GLsizei imageSize,
+                                    GLsizei dataSize,
+                                    const GLvoid *data);
+    void compressedTexImage3D(TextureType target,
                               GLint level,
                               GLenum internalformat,
                               GLsizei width,
                               GLsizei height,
                               GLsizei depth,
                               GLint border,
                               GLsizei imageSize,
                               const void *data);
-    void compressedTexSubImage2D(GLenum target,
+    void compressedTexImage3DRobust(TextureType target,
+                                    GLint level,
+                                    GLenum internalformat,
+                                    GLsizei width,
+                                    GLsizei height,
+                                    GLsizei depth,
+                                    GLint border,
+                                    GLsizei imageSize,
+                                    GLsizei dataSize,
+                                    const GLvoid *data);
+    void compressedTexSubImage2D(TextureTarget target,
                                  GLint level,
                                  GLint xoffset,
                                  GLint yoffset,
                                  GLsizei width,
                                  GLsizei height,
                                  GLenum format,
                                  GLsizei imageSize,
                                  const void *data);
-    void compressedTexSubImage3D(GLenum target,
+    void compressedTexSubImage2DRobust(TextureTarget target,
+                                       GLint level,
+                                       GLint xoffset,
+                                       GLint yoffset,
+                                       GLsizei width,
+                                       GLsizei height,
+                                       GLenum format,
+                                       GLsizei imageSize,
+                                       GLsizei dataSize,
+                                       const GLvoid *data);
+    void compressedTexSubImage3D(TextureType target,
                                  GLint level,
                                  GLint xoffset,
                                  GLint yoffset,
                                  GLint zoffset,
                                  GLsizei width,
                                  GLsizei height,
                                  GLsizei depth,
                                  GLenum format,
                                  GLsizei imageSize,
                                  const void *data);
+    void compressedTexSubImage3DRobust(TextureType target,
+                                       GLint level,
+                                       GLint xoffset,
+                                       GLint yoffset,
+                                       GLint zoffset,
+                                       GLsizei width,
+                                       GLsizei height,
+                                       GLsizei depth,
+                                       GLenum format,
+                                       GLsizei imageSize,
+                                       GLsizei dataSize,
+                                       const GLvoid *data);
     void copyTexture(GLuint sourceId,
                      GLint sourceLevel,
-                     GLenum destTarget,
+                     TextureTarget destTarget,
                      GLuint destId,
                      GLint destLevel,
                      GLint internalFormat,
                      GLenum destType,
                      GLboolean unpackFlipY,
                      GLboolean unpackPremultiplyAlpha,
                      GLboolean unpackUnmultiplyAlpha);
     void copySubTexture(GLuint sourceId,
                         GLint sourceLevel,
-                        GLenum destTarget,
+                        TextureTarget destTarget,
                         GLuint destId,
                         GLint destLevel,
                         GLint xoffset,
                         GLint yoffset,
                         GLint x,
                         GLint y,
                         GLsizei width,
                         GLsizei height,
                         GLboolean unpackFlipY,
                         GLboolean unpackPremultiplyAlpha,
                         GLboolean unpackUnmultiplyAlpha);
     void compressedCopyTexture(GLuint sourceId, GLuint destId);
 
-    void generateMipmap(GLenum target);
+    void generateMipmap(TextureType target);
 
     void flush();
     void finish();
 
     void getBufferPointerv(BufferBinding target, GLenum pname, void **params);
+    void getBufferPointervRobust(BufferBinding target,
+                                 GLenum pname,
+                                 GLsizei bufSize,
+                                 GLsizei *length,
+                                 void **params);
     void *mapBuffer(BufferBinding target, GLenum access);
     GLboolean unmapBuffer(BufferBinding target);
     void *mapBufferRange(BufferBinding target,
                          GLintptr offset,
                          GLsizeiptr length,
                          GLbitfield access);
     void flushMappedBufferRange(BufferBinding target, GLintptr offset, GLsizeiptr length);
 
@@ -697,21 +881,21 @@ class Context final : public ValidationC
                                         GLsizei samples,
                                         GLenum internalformat,
                                         GLsizei width,
                                         GLsizei height);
 
     void getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
 
     // CHROMIUM_framebuffer_mixed_samples
-    void setCoverageModulation(GLenum components);
+    void coverageModulation(GLenum components);
 
     // CHROMIUM_path_rendering
-    void loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix);
-    void loadPathRenderingIdentityMatrix(GLenum matrixMode);
+    void matrixLoadf(GLenum matrixMode, const GLfloat *matrix);
+    void matrixLoadIdentity(GLenum matrixMode);
     void stencilFillPath(GLuint path, GLenum fillMode, GLuint mask);
     void stencilStrokePath(GLuint path, GLint reference, GLuint mask);
     void coverFillPath(GLuint path, GLenum coverMode);
     void coverStrokePath(GLuint path, GLenum coverMode);
     void stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode);
     void stencilThenCoverStrokePath(GLuint path, GLint reference, GLuint mask, GLenum coverMode);
     void coverFillPathInstanced(GLsizei numPaths,
                                 GLenum pathNameType,
@@ -777,24 +961,29 @@ class Context final : public ValidationC
     void bindBufferRange(BufferBinding target,
                          GLuint index,
                          GLuint buffer,
                          GLintptr offset,
                          GLsizeiptr size);
     void bindFramebuffer(GLenum target, GLuint framebuffer);
     void bindRenderbuffer(GLenum target, GLuint renderbuffer);
 
-    void texStorage2DMultisample(GLenum target,
+    void texStorage2DMultisample(TextureType target,
                                  GLsizei samples,
                                  GLenum internalformat,
                                  GLsizei width,
                                  GLsizei height,
                                  GLboolean fixedsamplelocations);
 
     void getMultisamplefv(GLenum pname, GLuint index, GLfloat *val);
+    void getMultisamplefvRobust(GLenum pname,
+                                GLuint index,
+                                GLsizei bufSize,
+                                GLsizei *length,
+                                GLfloat *val);
 
     void copyBufferSubData(BufferBinding readTarget,
                            BufferBinding writeTarget,
                            GLintptr readOffset,
                            GLintptr writeOffset,
                            GLsizeiptr size);
 
     GLenum checkFramebufferStatus(GLenum target);
@@ -820,31 +1009,52 @@ class Context final : public ValidationC
                           GLsizei bufsize,
                           GLsizei *length,
                           GLint *size,
                           GLenum *type,
                           GLchar *name);
     void getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders);
     GLint getAttribLocation(GLuint program, const GLchar *name);
     void getProgramiv(GLuint program, GLenum pname, GLint *params);
+    void getProgramivRobust(GLuint program,
+                            GLenum pname,
+                            GLsizei bufSize,
+                            GLsizei *length,
+                            GLint *params);
     void getProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params);
     void getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog);
     void getProgramPipelineInfoLog(GLuint pipeline,
                                    GLsizei bufSize,
                                    GLsizei *length,
                                    GLchar *infoLog);
     void getShaderiv(GLuint shader, GLenum pname, GLint *params);
+    void getShaderivRobust(GLuint shader,
+                           GLenum pname,
+                           GLsizei bufSize,
+                           GLsizei *length,
+                           GLint *params);
+
     void getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog);
     void getShaderPrecisionFormat(GLenum shadertype,
                                   GLenum precisiontype,
                                   GLint *range,
                                   GLint *precision);
     void getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source);
     void getUniformfv(GLuint program, GLint location, GLfloat *params);
+    void getUniformfvRobust(GLuint program,
+                            GLint location,
+                            GLsizei bufSize,
+                            GLsizei *length,
+                            GLfloat *params);
     void getUniformiv(GLuint program, GLint location, GLint *params);
+    void getUniformivRobust(GLuint program,
+                            GLint location,
+                            GLsizei bufSize,
+                            GLsizei *length,
+                            GLint *params);
     GLint getUniformLocation(GLuint program, const GLchar *name);
     GLboolean isBuffer(GLuint buffer);
     GLboolean isEnabled(GLenum cap);
     GLboolean isFramebuffer(GLuint framebuffer);
     GLboolean isProgram(GLuint program);
     GLboolean isRenderbuffer(GLuint renderbuffer);
     GLboolean isShader(GLuint shader);
     GLboolean isTexture(GLuint texture);
@@ -948,53 +1158,76 @@ class Context final : public ValidationC
     void getProgramBinary(GLuint program,
                           GLsizei bufSize,
                           GLsizei *length,
                           GLenum *binaryFormat,
                           void *binary);
     void programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);
 
     void getUniformuiv(GLuint program, GLint location, GLuint *params);
+    void getUniformuivRobust(GLuint program,
+                             GLint location,
+                             GLsizei bufSize,
+                             GLsizei *length,
+                             GLuint *params);
     GLint getFragDataLocation(GLuint program, const GLchar *name);
     void getUniformIndices(GLuint program,
                            GLsizei uniformCount,
                            const GLchar *const *uniformNames,
                            GLuint *uniformIndices);
     void getActiveUniformsiv(GLuint program,
                              GLsizei uniformCount,
                              const GLuint *uniformIndices,
                              GLenum pname,
                              GLint *params);
     GLuint getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName);
     void getActiveUniformBlockiv(GLuint program,
                                  GLuint uniformBlockIndex,
                                  GLenum pname,
                                  GLint *params);
+    void getActiveUniformBlockivRobust(GLuint program,
+                                       GLuint uniformBlockIndex,
+                                       GLenum pname,
+                                       GLsizei bufSize,
+                                       GLsizei *length,
+                                       GLint *params);
     void getActiveUniformBlockName(GLuint program,
                                    GLuint uniformBlockIndex,
                                    GLsizei bufSize,
                                    GLsizei *length,
                                    GLchar *uniformBlockName);
     void uniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
 
     GLsync fenceSync(GLenum condition, GLbitfield flags);
     GLboolean isSync(GLsync sync);
     void deleteSync(GLsync sync);
     GLenum clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
     void waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
     void getInteger64v(GLenum pname, GLint64 *params);
+    void getInteger64vRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data);
 
     void getBufferParameteri64v(BufferBinding target, GLenum pname, GLint64 *params);
+    void getBufferParameteri64vRobust(BufferBinding target,
+                                      GLenum pname,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      GLint64 *params);
     void genSamplers(GLsizei count, GLuint *samplers);
     void deleteSamplers(GLsizei count, const GLuint *samplers);
     void getInternalformativ(GLenum target,
                              GLenum internalformat,
                              GLenum pname,
                              GLsizei bufSize,
                              GLint *params);
+    void getInternalformativRobust(GLenum target,
+                                   GLenum internalformat,
+                                   GLenum pname,
+                                   GLsizei bufSize,
+                                   GLsizei *length,
+                                   GLint *params);
 
     void programUniform1i(GLuint program, GLint location, GLint v0);
     void programUniform2i(GLuint program, GLint location, GLint v0, GLint v1);
     void programUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
     void programUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
     void programUniform1ui(GLuint program, GLint location, GLuint v0);
     void programUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1);
     void programUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
@@ -1081,52 +1314,72 @@ class Context final : public ValidationC
                                    const GLfloat *value);
 
     void deleteProgramPipelines(GLsizei n, const GLuint *pipelines);
     void genProgramPipelines(GLsizei n, GLuint *pipelines);
     GLboolean isProgramPipeline(GLuint pipeline);
 
     void getTranslatedShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source);
     void getnUniformfv(GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+    void getnUniformfvRobust(GLuint program,
+                             GLint location,
+                             GLsizei bufSize,
+                             GLsizei *length,
+                             GLfloat *params);
     void getnUniformiv(GLuint program, GLint location, GLsizei bufSize, GLint *params);
+    void getnUniformivRobust(GLuint program,
+                             GLint location,
+                             GLsizei bufSize,
+                             GLsizei *length,
+                             GLint *params);
+    void getnUniformuivRobust(GLuint program,
+                              GLint location,
+                              GLsizei bufSize,
+                              GLsizei *length,
+                              GLuint *params);
     void readnPixels(GLint x,
                      GLint y,
                      GLsizei width,
                      GLsizei height,
                      GLenum format,
                      GLenum type,
                      GLsizei bufSize,
                      void *data);
-    void eGLImageTargetTexture2D(GLenum target, GLeglImageOES image);
+    void eGLImageTargetTexture2D(TextureType target, GLeglImageOES image);
     void eGLImageTargetRenderbufferStorage(GLenum target, GLeglImageOES image);
 
     void getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params);
+    void getFramebufferParameterivRobust(GLenum target,
+                                         GLenum pname,
+                                         GLsizei bufSize,
+                                         GLsizei *length,
+                                         GLint *params);
     void framebufferParameteri(GLenum target, GLenum pname, GLint param);
 
     void dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ);
     void dispatchComputeIndirect(GLintptr indirect);
 
     void texStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
-    void texStorage2D(GLenum target,
+    void texStorage2D(TextureType target,
                       GLsizei levels,
                       GLenum internalFormat,
                       GLsizei width,
                       GLsizei height);
-    void texStorage3D(GLenum target,
+    void texStorage3D(TextureType target,
                       GLsizei levels,
                       GLenum internalFormat,
                       GLsizei width,
                       GLsizei height,
                       GLsizei depth);
 
     void memoryBarrier(GLbitfield barriers);
     void memoryBarrierByRegion(GLbitfield barriers);
 
     // Consumes the error.
-    void handleError(const Error &error) override;
+    void handleError(const Error &error);
 
     GLenum getError();
     void markContextLost();
     bool isContextLost();
     GLenum getGraphicsResetStatus();
     bool isResetNotificationEnabled();
 
     const egl::Config *getConfig() const;
@@ -1159,28 +1412,74 @@ class Context final : public ValidationC
     void onTextureChange(const Texture *texture);
 
     egl::Display *getCurrentDisplay() const { return mCurrentDisplay; }
     egl::Surface *getCurrentDrawSurface() const { return mCurrentSurface; }
     egl::Surface *getCurrentReadSurface() const { return mCurrentSurface; }
 
     bool isRobustResourceInitEnabled() const { return mGLState.isRobustResourceInitEnabled(); }
 
+    bool isCurrentTransformFeedback(const TransformFeedback *tf) const;
+    bool isCurrentVertexArray(const VertexArray *va) const;
+
+    const ContextState &getContextState() const { return mState; }
+    GLint getClientMajorVersion() const { return mState.getClientMajorVersion(); }
+    GLint getClientMinorVersion() const { return mState.getClientMinorVersion(); }
+    const Version &getClientVersion() const { return mState.getClientVersion(); }
+    const State &getGLState() const { return mState.getState(); }
+    const Caps &getCaps() const { return mState.getCaps(); }
+    const TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); }
+    const Extensions &getExtensions() const { return mState.getExtensions(); }
+    const Limitations &getLimitations() const { return mState.getLimitations(); }
+    bool skipValidation() const { return mSkipValidation; }
+
+    // Specific methods needed for validation.
+    bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
+    bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams);
+
+    Program *getProgram(GLuint handle) const;
+    Shader *getShader(GLuint handle) const;
+
+    bool isTextureGenerated(GLuint texture) const;
+    bool isBufferGenerated(GLuint buffer) const;
+    bool isRenderbufferGenerated(GLuint renderbuffer) const;
+    bool isFramebufferGenerated(GLuint framebuffer) const;
+    bool isProgramPipelineGenerated(GLuint pipeline) const;
+
+    bool usingDisplayTextureShareGroup() const;
+
+    // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
+    GLenum getConvertedRenderbufferFormat(GLenum internalformat) const;
+
+    bool isWebGL() const { return mState.isWebGL(); }
+    bool isWebGL1() const { return mState.isWebGL1(); }
+
+    template <typename T>
+    const T &getParams() const;
+
+    bool isValidBufferBinding(BufferBinding binding) const { return mValidBufferBindings[binding]; }
+
   private:
     Error prepareForDraw();
-    void syncRendererState();
-    void syncRendererState(const State::DirtyBits &bitMask, const State::DirtyObjects &objectMask);
-    void syncStateForReadPixels();
-    void syncStateForTexImage();
-    void syncStateForClear();
-    void syncStateForBlit();
+    Error prepareForClear(GLbitfield mask);
+    Error prepareForClearBuffer(GLenum buffer, GLint drawbuffer);
+    Error syncState();
+    Error syncState(const State::DirtyBits &bitMask, const State::DirtyObjects &objectMask);
+    Error syncDirtyBits();
+    Error syncDirtyBits(const State::DirtyBits &bitMask);
+    Error syncDirtyObjects();
+    Error syncDirtyObjects(const State::DirtyObjects &objectMask);
+    Error syncStateForReadPixels();
+    Error syncStateForTexImage();
+    Error syncStateForBlit();
+
     VertexArray *checkVertexArrayAllocation(GLuint vertexArrayHandle);
     TransformFeedback *checkTransformFeedbackAllocation(GLuint transformFeedback);
 
-    void detachBuffer(GLuint buffer);
+    void detachBuffer(Buffer *buffer);
     void detachTexture(GLuint texture);
     void detachFramebuffer(GLuint framebuffer);
     void detachRenderbuffer(GLuint renderbuffer);
     void detachVertexArray(GLuint vertexArray);
     void detachTransformFeedback(GLuint transformFeedback);
     void detachSampler(GLuint sampler);
     void detachProgramPipeline(GLuint pipeline);
 
@@ -1190,16 +1489,28 @@ class Context final : public ValidationC
 
     void initCaps(const egl::DisplayExtensions &displayExtensions, bool robustResourceInit);
     void updateCaps();
     void initWorkarounds();
 
     LabeledObject *getLabeledObject(GLenum identifier, GLuint name) const;
     LabeledObject *getLabeledObjectFromPtr(const void *ptr) const;
 
+    ContextState mState;
+    bool mSkipValidation;
+    bool mDisplayTextureShareGroup;
+
+    // Stores for each buffer binding type whether is it allowed to be used in this context.
+    angle::PackedEnumBitSet<BufferBinding> mValidBufferBindings;
+
+    // Caches entry point parameters and values re-used between layers.
+    mutable const ParamTypeInfo *mSavedArgsType;
+    static constexpr size_t kParamsBufferSize = 128u;
+    mutable std::array<uint8_t, kParamsBufferSize> mParamsBuffer;
+
     std::unique_ptr<rx::ContextImpl> mImplementation;
 
     // Caps to use for validation
     Caps mCaps;
     TextureCapsMap mTextureCaps;
     Extensions mExtensions;
     Limitations mLimitations;
 
@@ -1243,16 +1554,17 @@ class Context final : public ValidationC
     GLenum mResetStatus;
     bool mContextLostForced;
     GLenum mResetStrategy;
     bool mRobustAccess;
     egl::Surface *mCurrentSurface;
     egl::Display *mCurrentDisplay;
     Framebuffer *mSurfacelessFramebuffer;
     bool mWebGLContext;
+    bool mExtensionsEnabled;
     MemoryProgramCache *mMemoryProgramCache;
 
     State::DirtyBits mTexImageDirtyBits;
     State::DirtyObjects mTexImageDirtyObjects;
     State::DirtyBits mReadPixelsDirtyBits;
     State::DirtyObjects mReadPixelsDirtyObjects;
     State::DirtyBits mClearDirtyBits;
     State::DirtyObjects mClearDirtyObjects;
@@ -1263,16 +1575,24 @@ class Context final : public ValidationC
 
     Workarounds mWorkarounds;
 
     // Not really a property of context state. The size and contexts change per-api-call.
     mutable angle::ScratchBuffer mScratchBuffer;
     mutable angle::ScratchBuffer mZeroFilledBuffer;
 };
 
+template <typename T>
+const T &Context::getParams() const
+{
+    const T *params = reinterpret_cast<T *>(mParamsBuffer.data());
+    ASSERT(mSavedArgsType->hasDynamicType(T::TypeInfo));
+    return *params;
+}
+
 template <EntryPoint EP, typename... ArgsT>
 ANGLE_INLINE void Context::gatherParams(ArgsT &&... args)
 {
     static_assert(sizeof(EntryPointParamType<EP>) <= kParamsBufferSize,
                   "Params struct too large, please increase kParamsBufferSize.");
 
     mSavedArgsType = &EntryPointParamType<EP>::TypeInfo;
 
--- a/gfx/angle/checkout/src/libANGLE/ContextState.cpp
+++ b/gfx/angle/checkout/src/libANGLE/ContextState.cpp
@@ -108,769 +108,9 @@ bool ContextState::isWebGL1() const
     return (isWebGL() && mClientVersion.major == 2);
 }
 
 const TextureCaps &ContextState::getTextureCap(GLenum internalFormat) const
 {
     return mTextureCaps.get(internalFormat);
 }
 
-ValidationContext::ValidationContext(const ValidationContext *shareContext,
-                                     TextureManager *shareTextures,
-                                     const Version &clientVersion,
-                                     State *state,
-                                     const Caps &caps,
-                                     const TextureCapsMap &textureCaps,
-                                     const Extensions &extensions,
-                                     const Limitations &limitations,
-                                     bool skipValidation)
-    : mState(reinterpret_cast<ContextID>(this),
-             shareContext ? &shareContext->mState : nullptr,
-             shareTextures,
-             clientVersion,
-             state,
-             caps,
-             textureCaps,
-             extensions,
-             limitations),
-      mSkipValidation(skipValidation),
-      mDisplayTextureShareGroup(shareTextures != nullptr)
-{
-}
-
-ValidationContext::~ValidationContext()
-{
-}
-
-bool ValidationContext::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
-{
-    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
-    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
-    // to the fact that it is stored internally as a float, and so would require conversion
-    // if returned from Context::getIntegerv. Since this conversion is already implemented
-    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
-    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
-    // application.
-    switch (pname)
-    {
-        case GL_COMPRESSED_TEXTURE_FORMATS:
-        {
-            *type      = GL_INT;
-            *numParams = static_cast<unsigned int>(getCaps().compressedTextureFormats.size());
-            return true;
-        }
-        case GL_SHADER_BINARY_FORMATS:
-        {
-            *type      = GL_INT;
-            *numParams = static_cast<unsigned int>(getCaps().shaderBinaryFormats.size());
-            return true;
-        }
-
-        case GL_MAX_VERTEX_ATTRIBS:
-        case GL_MAX_VERTEX_UNIFORM_VECTORS:
-        case GL_MAX_VARYING_VECTORS:
-        case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
-        case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
-        case GL_MAX_TEXTURE_IMAGE_UNITS:
-        case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
-        case GL_MAX_RENDERBUFFER_SIZE:
-        case GL_NUM_SHADER_BINARY_FORMATS:
-        case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
-        case GL_ARRAY_BUFFER_BINDING:
-        case GL_FRAMEBUFFER_BINDING:
-        case GL_RENDERBUFFER_BINDING:
-        case GL_CURRENT_PROGRAM:
-        case GL_PACK_ALIGNMENT:
-        case GL_UNPACK_ALIGNMENT:
-        case GL_GENERATE_MIPMAP_HINT:
-        case GL_RED_BITS:
-        case GL_GREEN_BITS:
-        case GL_BLUE_BITS:
-        case GL_ALPHA_BITS:
-        case GL_DEPTH_BITS:
-        case GL_STENCIL_BITS:
-        case GL_ELEMENT_ARRAY_BUFFER_BINDING:
-        case GL_CULL_FACE_MODE:
-        case GL_FRONT_FACE:
-        case GL_ACTIVE_TEXTURE:
-        case GL_STENCIL_FUNC:
-        case GL_STENCIL_VALUE_MASK:
-        case GL_STENCIL_REF:
-        case GL_STENCIL_FAIL:
-        case GL_STENCIL_PASS_DEPTH_FAIL:
-        case GL_STENCIL_PASS_DEPTH_PASS:
-        case GL_STENCIL_BACK_FUNC:
-        case GL_STENCIL_BACK_VALUE_MASK:
-        case GL_STENCIL_BACK_REF:
-        case GL_STENCIL_BACK_FAIL:
-        case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
-        case GL_STENCIL_BACK_PASS_DEPTH_PASS:
-        case GL_DEPTH_FUNC:
-        case GL_BLEND_SRC_RGB:
-        case GL_BLEND_SRC_ALPHA:
-        case GL_BLEND_DST_RGB:
-        case GL_BLEND_DST_ALPHA:
-        case GL_BLEND_EQUATION_RGB:
-        case GL_BLEND_EQUATION_ALPHA:
-        case GL_STENCIL_WRITEMASK:
-        case GL_STENCIL_BACK_WRITEMASK:
-        case GL_STENCIL_CLEAR_VALUE:
-        case GL_SUBPIXEL_BITS:
-        case GL_MAX_TEXTURE_SIZE:
-        case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
-        case GL_SAMPLE_BUFFERS:
-        case GL_SAMPLES:
-        case GL_IMPLEMENTATION_COLOR_READ_TYPE:
-        case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
-        case GL_TEXTURE_BINDING_2D:
-        case GL_TEXTURE_BINDING_CUBE_MAP:
-        case GL_RESET_NOTIFICATION_STRATEGY_EXT:
-        {
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-        }
-        case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
-        {
-            if (!getExtensions().packReverseRowOrder)
-            {
-                return false;
-            }
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-        }
-        case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
-        case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
-        {
-            if (!getExtensions().textureRectangle)
-            {
-                return false;
-            }
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-        }
-        case GL_MAX_DRAW_BUFFERS_EXT:
-        case GL_MAX_COLOR_ATTACHMENTS_EXT:
-        {
-            if ((getClientMajorVersion() < 3) && !getExtensions().drawBuffers)
-            {
-                return false;
-            }
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-        }
-        case GL_MAX_VIEWPORT_DIMS:
-        {
-            *type      = GL_INT;
-            *numParams = 2;
-            return true;
-        }
-        case GL_VIEWPORT:
-        case GL_SCISSOR_BOX:
-        {
-            *type      = GL_INT;
-            *numParams = 4;
-            return true;
-        }
-        case GL_SHADER_COMPILER:
-        case GL_SAMPLE_COVERAGE_INVERT:
-        case GL_DEPTH_WRITEMASK:
-        case GL_CULL_FACE:                 // CULL_FACE through DITHER are natural to IsEnabled,
-        case GL_POLYGON_OFFSET_FILL:       // but can be retrieved through the Get{Type}v queries.
-        case GL_SAMPLE_ALPHA_TO_COVERAGE:  // For this purpose, they are treated here as
-                                           // bool-natural
-        case GL_SAMPLE_COVERAGE:
-        case GL_SCISSOR_TEST:
-        case GL_STENCIL_TEST:
-        case GL_DEPTH_TEST:
-        case GL_BLEND:
-        case GL_DITHER:
-        case GL_CONTEXT_ROBUST_ACCESS_EXT:
-        {
-            *type      = GL_BOOL;
-            *numParams = 1;
-            return true;
-        }
-        case GL_COLOR_WRITEMASK:
-        {
-            *type      = GL_BOOL;
-            *numParams = 4;
-            return true;
-        }
-        case GL_POLYGON_OFFSET_FACTOR:
-        case GL_POLYGON_OFFSET_UNITS:
-        case GL_SAMPLE_COVERAGE_VALUE:
-        case GL_DEPTH_CLEAR_VALUE:
-        case GL_LINE_WIDTH:
-        {
-            *type      = GL_FLOAT;
-            *numParams = 1;
-            return true;
-        }
-        case GL_ALIASED_LINE_WIDTH_RANGE:
-        case GL_ALIASED_POINT_SIZE_RANGE:
-        case GL_DEPTH_RANGE:
-        {
-            *type      = GL_FLOAT;
-            *numParams = 2;
-            return true;
-        }
-        case GL_COLOR_CLEAR_VALUE:
-        case GL_BLEND_COLOR:
-        {
-            *type      = GL_FLOAT;
-            *numParams = 4;
-            return true;
-        }
-        case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
-            if (!getExtensions().textureFilterAnisotropic)
-            {
-                return false;
-            }
-            *type      = GL_FLOAT;
-            *numParams = 1;
-            return true;
-        case GL_TIMESTAMP_EXT:
-            if (!getExtensions().disjointTimerQuery)
-            {
-                return false;
-            }
-            *type      = GL_INT_64_ANGLEX;
-            *numParams = 1;
-            return true;
-        case GL_GPU_DISJOINT_EXT:
-            if (!getExtensions().disjointTimerQuery)
-            {
-                return false;
-            }
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-        case GL_COVERAGE_MODULATION_CHROMIUM:
-            if (!getExtensions().framebufferMixedSamples)
-            {
-                return false;
-            }
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-        case GL_TEXTURE_BINDING_EXTERNAL_OES:
-            if (!getExtensions().eglStreamConsumerExternal && !getExtensions().eglImageExternal)
-            {
-                return false;
-            }
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-    }
-
-    if (getExtensions().debug)
-    {
-        switch (pname)
-        {
-            case GL_DEBUG_LOGGED_MESSAGES:
-            case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
-            case GL_DEBUG_GROUP_STACK_DEPTH:
-            case GL_MAX_DEBUG_MESSAGE_LENGTH:
-            case GL_MAX_DEBUG_LOGGED_MESSAGES:
-            case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
-            case GL_MAX_LABEL_LENGTH:
-                *type      = GL_INT;
-                *numParams = 1;
-                return true;
-
-            case GL_DEBUG_OUTPUT_SYNCHRONOUS:
-            case GL_DEBUG_OUTPUT:
-                *type      = GL_BOOL;
-                *numParams = 1;
-                return true;
-        }
-    }
-
-    if (getExtensions().multisampleCompatibility)
-    {
-        switch (pname)
-        {
-            case GL_MULTISAMPLE_EXT:
-            case GL_SAMPLE_ALPHA_TO_ONE_EXT:
-                *type      = GL_BOOL;
-                *numParams = 1;
-                return true;
-        }
-    }
-
-    if (getExtensions().pathRendering)
-    {
-        switch (pname)
-        {
-            case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
-            case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
-                *type = GL_FLOAT;
-                *numParams = 16;
-                return true;
-        }
-    }
-
-    if (getExtensions().bindGeneratesResource)
-    {
-        switch (pname)
-        {
-            case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
-                *type      = GL_BOOL;
-                *numParams = 1;
-                return true;
-        }
-    }
-
-    if (getExtensions().clientArrays)
-    {
-        switch (pname)
-        {
-            case GL_CLIENT_ARRAYS_ANGLE:
-                *type      = GL_BOOL;
-                *numParams = 1;
-                return true;
-        }
-    }
-
-    if (getExtensions().sRGBWriteControl)
-    {
-        switch (pname)
-        {
-            case GL_FRAMEBUFFER_SRGB_EXT:
-                *type      = GL_BOOL;
-                *numParams = 1;
-                return true;
-        }
-    }
-
-    if (getExtensions().robustResourceInitialization &&
-        pname == GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE)
-    {
-        *type      = GL_BOOL;
-        *numParams = 1;
-        return true;
-    }
-
-    if (getExtensions().programCacheControl && pname == GL_PROGRAM_CACHE_ENABLED_ANGLE)
-    {
-        *type      = GL_BOOL;
-        *numParams = 1;
-        return true;
-    }
-
-    // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
-    switch (pname)
-    {
-        // case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE  // equivalent to FRAMEBUFFER_BINDING
-        case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
-            if ((getClientMajorVersion() < 3) && !getExtensions().framebufferBlit)
-            {
-                return false;
-            }
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-
-        case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
-            if ((getClientMajorVersion() < 3) && !getExtensions().getProgramBinary)
-            {
-                return false;
-            }
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-
-        case GL_PROGRAM_BINARY_FORMATS_OES:
-            if ((getClientMajorVersion() < 3) && !getExtensions().getProgramBinary)
-            {
-                return false;
-            }
-            *type      = GL_INT;
-            *numParams = static_cast<unsigned int>(getCaps().programBinaryFormats.size());
-            return true;
-
-        case GL_PACK_ROW_LENGTH:
-        case GL_PACK_SKIP_ROWS:
-        case GL_PACK_SKIP_PIXELS:
-            if ((getClientMajorVersion() < 3) && !getExtensions().packSubimage)
-            {
-                return false;
-            }
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-        case GL_UNPACK_ROW_LENGTH:
-        case GL_UNPACK_SKIP_ROWS:
-        case GL_UNPACK_SKIP_PIXELS:
-            if ((getClientMajorVersion() < 3) && !getExtensions().unpackSubimage)
-            {
-                return false;
-            }
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-        case GL_VERTEX_ARRAY_BINDING:
-            if ((getClientMajorVersion() < 3) && !getExtensions().vertexArrayObject)
-            {
-                return false;
-            }
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-        case GL_PIXEL_PACK_BUFFER_BINDING:
-        case GL_PIXEL_UNPACK_BUFFER_BINDING:
-            if ((getClientMajorVersion() < 3) && !getExtensions().pixelBufferObject)
-            {
-                return false;
-            }
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-        case GL_MAX_SAMPLES:
-        {
-            static_assert(GL_MAX_SAMPLES_ANGLE == GL_MAX_SAMPLES,
-                          "GL_MAX_SAMPLES_ANGLE not equal to GL_MAX_SAMPLES");
-            if ((getClientMajorVersion() < 3) && !getExtensions().framebufferMultisample)
-            {
-                return false;
-            }
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-
-            case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
-                if ((getClientMajorVersion() < 3) && !getExtensions().standardDerivatives)
-                {
-                    return false;
-                }
-                *type      = GL_INT;
-                *numParams = 1;
-                return true;
-        }
-    }
-
-    if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
-    {
-        if ((getClientVersion() < Version(3, 0)) && !getExtensions().drawBuffers)
-        {
-            return false;
-        }
-        *type      = GL_INT;
-        *numParams = 1;
-        return true;
-    }
-
-    if (getExtensions().multiview && pname == GL_MAX_VIEWS_ANGLE)
-    {
-        *type      = GL_INT;
-        *numParams = 1;
-        return true;
-    }
-
-    if (getClientVersion() < Version(3, 0))
-    {
-        return false;
-    }
-
-    // Check for ES3.0+ parameter names
-    switch (pname)
-    {
-        case GL_MAX_UNIFORM_BUFFER_BINDINGS:
-        case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
-        case GL_UNIFORM_BUFFER_BINDING:
-        case GL_TRANSFORM_FEEDBACK_BINDING:
-        case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
-        case GL_COPY_READ_BUFFER_BINDING:
-        case GL_COPY_WRITE_BUFFER_BINDING:
-        case GL_SAMPLER_BINDING:
-        case GL_READ_BUFFER:
-        case GL_TEXTURE_BINDING_3D:
-        case GL_TEXTURE_BINDING_2D_ARRAY:
-        case GL_MAX_3D_TEXTURE_SIZE:
-        case GL_MAX_ARRAY_TEXTURE_LAYERS:
-        case GL_MAX_VERTEX_UNIFORM_BLOCKS:
-        case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
-        case GL_MAX_COMBINED_UNIFORM_BLOCKS:
-        case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
-        case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
-        case GL_MAX_VARYING_COMPONENTS:
-        case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
-        case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
-        case GL_MIN_PROGRAM_TEXEL_OFFSET:
-        case GL_MAX_PROGRAM_TEXEL_OFFSET:
-        case GL_NUM_EXTENSIONS:
-        case GL_MAJOR_VERSION:
-        case GL_MINOR_VERSION:
-        case GL_MAX_ELEMENTS_INDICES:
-        case GL_MAX_ELEMENTS_VERTICES:
-        case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
-        case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
-        case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
-        case GL_UNPACK_IMAGE_HEIGHT:
-        case GL_UNPACK_SKIP_IMAGES:
-        {
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-        }
-
-        case GL_MAX_ELEMENT_INDEX:
-        case GL_MAX_UNIFORM_BLOCK_SIZE:
-        case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
-        case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
-        case GL_MAX_SERVER_WAIT_TIMEOUT:
-        {
-            *type      = GL_INT_64_ANGLEX;
-            *numParams = 1;
-            return true;
-        }
-
-        case GL_TRANSFORM_FEEDBACK_ACTIVE:
-        case GL_TRANSFORM_FEEDBACK_PAUSED:
-        case GL_PRIMITIVE_RESTART_FIXED_INDEX:
-        case GL_RASTERIZER_DISCARD:
-        {
-            *type      = GL_BOOL;
-            *numParams = 1;
-            return true;
-        }
-
-        case GL_MAX_TEXTURE_LOD_BIAS:
-        {
-            *type      = GL_FLOAT;
-            *numParams = 1;
-            return true;
-        }
-    }
-
-    if (getExtensions().requestExtension)
-    {
-        switch (pname)
-        {
-            case GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE:
-                *type      = GL_INT;
-                *numParams = 1;
-                return true;
-        }
-    }
-
-    if (getClientVersion() < Version(3, 1))
-    {
-        return false;
-    }
-
-    switch (pname)
-    {
-        case GL_ATOMIC_COUNTER_BUFFER_BINDING:
-        case GL_DRAW_INDIRECT_BUFFER_BINDING:
-        case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
-        case GL_MAX_FRAMEBUFFER_WIDTH:
-        case GL_MAX_FRAMEBUFFER_HEIGHT:
-        case GL_MAX_FRAMEBUFFER_SAMPLES:
-        case GL_MAX_SAMPLE_MASK_WORDS:
-        case GL_MAX_COLOR_TEXTURE_SAMPLES:
-        case GL_MAX_DEPTH_TEXTURE_SAMPLES:
-        case GL_MAX_INTEGER_SAMPLES:
-        case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
-        case GL_MAX_VERTEX_ATTRIB_BINDINGS:
-        case GL_MAX_VERTEX_ATTRIB_STRIDE:
-        case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
-        case GL_MAX_VERTEX_ATOMIC_COUNTERS:
-        case GL_MAX_VERTEX_IMAGE_UNIFORMS:
-        case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
-        case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
-        case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
-        case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
-        case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
-        case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
-        case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
-        case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
-        case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
-        case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
-        case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
-        case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
-        case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
-        case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
-        case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
-        case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
-        case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
-        case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
-        case GL_MAX_UNIFORM_LOCATIONS:
-        case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
-        case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
-        case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
-        case GL_MAX_COMBINED_ATOMIC_COUNTERS:
-        case GL_MAX_IMAGE_UNITS:
-        case GL_MAX_COMBINED_IMAGE_UNIFORMS:
-        case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
-        case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
-        case GL_SHADER_STORAGE_BUFFER_BINDING:
-        case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
-        case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-        case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
-            *type      = GL_INT_64_ANGLEX;
-            *numParams = 1;
-            return true;
-        case GL_SAMPLE_MASK:
-            *type      = GL_BOOL;
-            *numParams = 1;
-            return true;
-    }
-
-    if (getExtensions().geometryShader)
-    {
-        switch (pname)
-        {
-            case GL_MAX_FRAMEBUFFER_LAYERS_EXT:
-            case GL_LAYER_PROVOKING_VERTEX_EXT:
-            case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT:
-            case GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT:
-            case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT:
-            case GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT:
-            case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT:
-            case GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT:
-            case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT:
-            case GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT:
-            case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT:
-            case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT:
-            case GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT:
-            case GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT:
-            case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT:
-                *type      = GL_INT;
-                *numParams = 1;
-                return true;
-        }
-    }
-
-    return false;
-}
-
-bool ValidationContext::getIndexedQueryParameterInfo(GLenum target,
-                                                     GLenum *type,
-                                                     unsigned int *numParams)
-{
-    if (getClientVersion() < Version(3, 0))
-    {
-        return false;
-    }
-
-    switch (target)
-    {
-        case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
-        case GL_UNIFORM_BUFFER_BINDING:
-        {
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-        }
-        case GL_TRANSFORM_FEEDBACK_BUFFER_START:
-        case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
-        case GL_UNIFORM_BUFFER_START:
-        case GL_UNIFORM_BUFFER_SIZE:
-        {
-            *type      = GL_INT_64_ANGLEX;
-            *numParams = 1;
-            return true;
-        }
-    }
-
-    if (getClientVersion() < Version(3, 1))
-    {
-        return false;
-    }
-
-    switch (target)
-    {
-        case GL_IMAGE_BINDING_LAYERED:
-        {
-            *type      = GL_BOOL;
-            *numParams = 1;
-            return true;
-        }
-        case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
-        case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
-        case GL_ATOMIC_COUNTER_BUFFER_BINDING:
-        case GL_SHADER_STORAGE_BUFFER_BINDING:
-        case GL_VERTEX_BINDING_BUFFER:
-        case GL_VERTEX_BINDING_DIVISOR:
-        case GL_VERTEX_BINDING_OFFSET:
-        case GL_VERTEX_BINDING_STRIDE:
-        case GL_SAMPLE_MASK_VALUE:
-        case GL_IMAGE_BINDING_NAME:
-        case GL_IMAGE_BINDING_LEVEL:
-        case GL_IMAGE_BINDING_LAYER:
-        case GL_IMAGE_BINDING_ACCESS:
-        case GL_IMAGE_BINDING_FORMAT:
-        {
-            *type      = GL_INT;
-            *numParams = 1;
-            return true;
-        }
-        case GL_ATOMIC_COUNTER_BUFFER_START:
-        case GL_ATOMIC_COUNTER_BUFFER_SIZE:
-        case GL_SHADER_STORAGE_BUFFER_START:
-        case GL_SHADER_STORAGE_BUFFER_SIZE:
-        {
-            *type      = GL_INT_64_ANGLEX;
-            *numParams = 1;
-            return true;
-        }
-    }
-
-    return false;
-}
-
-Program *ValidationContext::getProgram(GLuint handle) const
-{
-    return mState.mShaderPrograms->getProgram(handle);
-}
-
-Shader *ValidationContext::getShader(GLuint handle) const
-{
-    return mState.mShaderPrograms->getShader(handle);
-}
-
-bool ValidationContext::isTextureGenerated(GLuint texture) const
-{
-    return mState.mTextures->isHandleGenerated(texture);
-}
-
-bool ValidationContext::isBufferGenerated(GLuint buffer) const
-{
-    return mState.mBuffers->isHandleGenerated(buffer);
-}
-
-bool ValidationContext::isRenderbufferGenerated(GLuint renderbuffer) const
-{
-    return mState.mRenderbuffers->isHandleGenerated(renderbuffer);
-}
-
-bool ValidationContext::isFramebufferGenerated(GLuint framebuffer) const
-{
-    return mState.mFramebuffers->isHandleGenerated(framebuffer);
-}
-
-bool ValidationContext::isProgramPipelineGenerated(GLuint pipeline) const
-{
-    return mState.mPipelines->isHandleGenerated(pipeline);
-}
-
-bool ValidationContext::usingDisplayTextureShareGroup() const
-{
-    return mDisplayTextureShareGroup;
-}
-
-GLenum ValidationContext::getConvertedRenderbufferFormat(GLenum internalformat) const
-{
-    return mState.mExtensions.webglCompatibility && mState.mClientVersion.major == 2 &&
-                   internalformat == GL_DEPTH_STENCIL
-               ? GL_DEPTH24_STENCIL8
-               : internalformat;
-}
-
 }  // namespace gl
--- a/gfx/angle/checkout/src/libANGLE/ContextState.h
+++ b/gfx/angle/checkout/src/libANGLE/ContextState.h
@@ -22,17 +22,16 @@ class ContextState;
 class FramebufferManager;
 class PathManager;
 class ProgramPipelineManager;
 class RenderbufferManager;
 class SamplerManager;
 class ShaderProgramManager;
 class SyncManager;
 class TextureManager;
-class ValidationContext;
 
 static constexpr Version ES_2_0 = Version(2, 0);
 static constexpr Version ES_3_0 = Version(3, 0);
 static constexpr Version ES_3_1 = Version(3, 1);
 
 using ContextID = uintptr_t;
 
 class ContextState final : angle::NonCopyable
@@ -56,24 +55,21 @@ class ContextState final : angle::NonCop
     const State &getState() const { return *mState; }
     const Caps &getCaps() const { return mCaps; }
     const TextureCapsMap &getTextureCaps() const { return mTextureCaps; }
     const Extensions &getExtensions() const { return mExtensions; }
     const Limitations &getLimitations() const { return mLimitations; }
 
     const TextureCaps &getTextureCap(GLenum internalFormat) const;
 
-    bool usingDisplayTextureShareGroup() const;
-
     bool isWebGL() const;
     bool isWebGL1() const;
 
   private:
     friend class Context;
-    friend class ValidationContext;
 
     Version mClientVersion;
     ContextID mContext;
     State *mState;
     const Caps &mCaps;
     const TextureCapsMap &mTextureCaps;
     const Extensions &mExtensions;
     const Limitations &mLimitations;
@@ -84,86 +80,11 @@ class ContextState final : angle::NonCop
     RenderbufferManager *mRenderbuffers;
     SamplerManager *mSamplers;
     SyncManager *mSyncs;
     PathManager *mPaths;
     FramebufferManager *mFramebuffers;
     ProgramPipelineManager *mPipelines;
 };
 
-class ValidationContext : angle::NonCopyable
-{
-  public:
-    ValidationContext(const ValidationContext *shareContext,
-                      TextureManager *shareTextures,
-                      const Version &clientVersion,
-                      State *state,
-                      const Caps &caps,
-                      const TextureCapsMap &textureCaps,
-                      const Extensions &extensions,
-                      const Limitations &limitations,
-                      bool skipValidation);
-    virtual ~ValidationContext();
-
-    virtual void handleError(const Error &error) = 0;
-
-    const ContextState &getContextState() const { return mState; }
-    GLint getClientMajorVersion() const { return mState.getClientMajorVersion(); }
-    GLint getClientMinorVersion() const { return mState.getClientMinorVersion(); }
-    const Version &getClientVersion() const { return mState.getClientVersion(); }
-    const State &getGLState() const { return mState.getState(); }
-    const Caps &getCaps() const { return mState.getCaps(); }
-    const TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); }
-    const Extensions &getExtensions() const { return mState.getExtensions(); }
-    const Limitations &getLimitations() const { return mState.getLimitations(); }
-    bool skipValidation() const { return mSkipValidation; }
-
-    // Specific methods needed for validation.
-    bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
-    bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams);
-
-    Program *getProgram(GLuint handle) const;
-    Shader *getShader(GLuint handle) const;
-
-    bool isTextureGenerated(GLuint texture) const;
-    bool isBufferGenerated(GLuint buffer) const;
-    bool isRenderbufferGenerated(GLuint renderbuffer) const;
-    bool isFramebufferGenerated(GLuint framebuffer) const;
-    bool isProgramPipelineGenerated(GLuint pipeline) const;
-
-    bool usingDisplayTextureShareGroup() const;
-
-    // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
-    GLenum getConvertedRenderbufferFormat(GLenum internalformat) const;
-
-    bool isWebGL() const { return mState.isWebGL(); }
-    bool isWebGL1() const { return mState.isWebGL1(); }
-
-    template <typename T>
-    const T &getParams() const;
-
-    bool isValidBufferBinding(BufferBinding binding) const { return mValidBufferBindings[binding]; }
-
-  protected:
-    ContextState mState;
-    bool mSkipValidation;
-    bool mDisplayTextureShareGroup;
-
-    // Stores for each buffer binding type whether is it allowed to be used in this context.
-    angle::PackedEnumBitSet<BufferBinding> mValidBufferBindings;
-
-    // Caches entry point parameters and values re-used between layers.
-    mutable const ParamTypeInfo *mSavedArgsType;
-    static constexpr size_t kParamsBufferSize = 64u;
-    mutable std::array<uint8_t, kParamsBufferSize> mParamsBuffer;
-};
-
-template <typename T>
-const T &ValidationContext::getParams() const
-{
-    const T *params = reinterpret_cast<T *>(mParamsBuffer.data());
-    ASSERT(mSavedArgsType->hasDynamicType(T::TypeInfo));
-    return *params;
-}
-
 }  // namespace gl
 
 #endif  // LIBANGLE_CONTEXTSTATE_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context_gles_1_0.cpp
@@ -0,0 +1,599 @@
+//
+// 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.
+//
+
+// Context_gles_1_0.cpp: Implements the GLES1-specific parts of Context.
+
+#include "libANGLE/Context.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
+
+namespace
+{
+
+angle::Mat4 FixedMatrixToMat4(const GLfixed *m)
+{
+    angle::Mat4 matrixAsFloat;
+    GLfloat *floatData = matrixAsFloat.data();
+
+    for (int i = 0; i < 16; i++)
+    {
+        floatData[i] = gl::FixedToFloat(m[i]);
+    }
+
+    return matrixAsFloat;
+}
+
+}  // namespace
+
+namespace gl
+{
+
+void Context::alphaFunc(AlphaTestFunc func, GLfloat ref)
+{
+    mGLState.gles1().setAlphaFunc(func, ref);
+}
+
+void Context::alphaFuncx(AlphaTestFunc func, GLfixed ref)
+{
+    mGLState.gles1().setAlphaFunc(func, FixedToFloat(ref));
+}
+
+void Context::clearColorx(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::clearDepthx(GLfixed depth)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::clientActiveTexture(GLenum texture)
+{
+    mGLState.gles1().setClientTextureUnit(texture - GL_TEXTURE0);
+}
+
+void Context::clipPlanef(GLenum p, const GLfloat *eqn)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::clipPlanex(GLenum plane, const GLfixed *equation)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+    mGLState.gles1().setCurrentColor({red, green, blue, alpha});
+}
+
+void Context::color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+    mGLState.gles1().setCurrentColor(
+        {normalizedToFloat<uint8_t>(red), normalizedToFloat<uint8_t>(green),
+         normalizedToFloat<uint8_t>(blue), normalizedToFloat<uint8_t>(alpha)});
+}
+
+void Context::color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+    mGLState.gles1().setCurrentColor(
+        {FixedToFloat(red), FixedToFloat(green), FixedToFloat(blue), FixedToFloat(alpha)});
+}
+
+void Context::colorPointer(GLint size, GLenum type, GLsizei stride, const void *ptr)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::depthRangex(GLfixed n, GLfixed f)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::disableClientState(GLenum clientState)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::enableClientState(GLenum clientState)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::fogf(GLenum pname, GLfloat param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::fogfv(GLenum pname, const GLfloat *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::fogx(GLenum pname, GLfixed param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::fogxv(GLenum pname, const GLfixed *param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::frustumf(GLfloat left,
+                       GLfloat right,
+                       GLfloat bottom,
+                       GLfloat top,
+                       GLfloat zNear,
+                       GLfloat zFar)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::frustumx(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getClipPlanef(GLenum plane, GLfloat *equation)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getClipPlanex(GLenum plane, GLfixed *equation)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getFixedv(GLenum pname, GLfixed *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getLightfv(GLenum light, GLenum pname, GLfloat *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getLightxv(GLenum light, GLenum pname, GLfixed *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getMaterialfv(GLenum face, GLenum pname, GLfloat *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getMaterialxv(GLenum face, GLenum pname, GLfixed *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getTexEnvfv(GLenum env, GLenum pname, GLfloat *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getTexEnviv(GLenum env, GLenum pname, GLint *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getTexEnvxv(GLenum target, GLenum pname, GLfixed *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getTexParameterxv(TextureType target, GLenum pname, GLfixed *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::lightModelf(GLenum pname, GLfloat param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::lightModelfv(GLenum pname, const GLfloat *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::lightModelx(GLenum pname, GLfixed param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::lightModelxv(GLenum pname, const GLfixed *param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::lightf(GLenum light, GLenum pname, GLfloat param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::lightfv(GLenum light, GLenum pname, const GLfloat *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::lightx(GLenum light, GLenum pname, GLfixed param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::lightxv(GLenum light, GLenum pname, const GLfixed *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::lineWidthx(GLfixed width)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::loadIdentity()
+{
+    mGLState.gles1().loadMatrix(angle::Mat4());
+}
+
+void Context::loadMatrixf(const GLfloat *m)
+{
+    mGLState.gles1().loadMatrix(angle::Mat4(m));
+}
+
+void Context::loadMatrixx(const GLfixed *m)
+{
+    mGLState.gles1().loadMatrix(FixedMatrixToMat4(m));
+}
+
+void Context::logicOp(GLenum opcode)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::materialf(GLenum face, GLenum pname, GLfloat param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::materialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::materialx(GLenum face, GLenum pname, GLfixed param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::materialxv(GLenum face, GLenum pname, const GLfixed *param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::matrixMode(MatrixType mode)
+{
+    mGLState.gles1().setMatrixMode(mode);
+}
+
+void Context::multMatrixf(const GLfloat *m)
+{
+    mGLState.gles1().multMatrix(angle::Mat4(m));
+}
+
+void Context::multMatrixx(const GLfixed *m)
+{
+    mGLState.gles1().multMatrix(FixedMatrixToMat4(m));
+}
+
+void Context::multiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+    unsigned int unit = target - GL_TEXTURE0;
+    ASSERT(target >= GL_TEXTURE0 && unit < getCaps().maxMultitextureUnits);
+    mGLState.gles1().setCurrentTextureCoords(unit, {s, t, r, q});
+}
+
+void Context::multiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+    unsigned int unit = target - GL_TEXTURE0;
+    ASSERT(target >= GL_TEXTURE0 && unit < getCaps().maxMultitextureUnits);
+    mGLState.gles1().setCurrentTextureCoords(
+        unit, {FixedToFloat(s), FixedToFloat(t), FixedToFloat(r), FixedToFloat(q)});
+}
+
+void Context::normal3f(GLfloat nx, GLfloat ny, GLfloat nz)
+{
+    mGLState.gles1().setCurrentNormal({nx, ny, nz});
+}
+
+void Context::normal3x(GLfixed nx, GLfixed ny, GLfixed nz)
+{
+    mGLState.gles1().setCurrentNormal({FixedToFloat(nx), FixedToFloat(ny), FixedToFloat(nz)});
+}
+
+void Context::normalPointer(GLenum type, GLsizei stride, const void *ptr)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::orthof(GLfloat left,
+                     GLfloat right,
+                     GLfloat bottom,
+                     GLfloat top,
+                     GLfloat zNear,
+                     GLfloat zFar)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::orthox(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::pointParameterf(GLenum pname, GLfloat param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::pointParameterfv(GLenum pname, const GLfloat *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::pointParameterx(GLenum pname, GLfixed param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::pointParameterxv(GLenum pname, const GLfixed *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::pointSize(GLfloat size)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::pointSizex(GLfixed size)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::polygonOffsetx(GLfixed factor, GLfixed units)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::popMatrix()
+{
+    mGLState.gles1().popMatrix();
+}
+
+void Context::pushMatrix()
+{
+    mGLState.gles1().pushMatrix();
+}
+
+void Context::rotatef(float angle, float x, float y, float z)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::sampleCoveragex(GLclampx value, GLboolean invert)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::scalef(float x, float y, float z)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::scalex(GLfixed x, GLfixed y, GLfixed z)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::shadeModel(GLenum mode)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::texCoordPointer(GLint size, GLenum type, GLsizei stride, const void *ptr)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::texEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::texEnvfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::texEnvi(GLenum target, GLenum pname, GLint param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::texEnviv(GLenum target, GLenum pname, const GLint *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::texEnvx(GLenum target, GLenum pname, GLfixed param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::texEnvxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::texParameterx(TextureType target, GLenum pname, GLfixed param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::texParameterxv(TextureType target, GLenum pname, const GLfixed *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::translatef(float x, float y, float z)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::translatex(GLfixed x, GLfixed y, GLfixed z)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::vertexPointer(GLint size, GLenum type, GLsizei stride, const void *ptr)
+{
+    UNIMPLEMENTED();
+}
+
+// GL_OES_draw_texture
+void Context::drawTexf(float x, float y, float z, float width, float height)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::drawTexfv(const GLfloat *coords)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::drawTexi(GLint x, GLint y, GLint z, GLint width, GLint height)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::drawTexiv(const GLint *coords)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::drawTexs(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::drawTexsv(const GLshort *coords)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::drawTexx(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::drawTexxv(const GLfixed *coords)
+{
+    UNIMPLEMENTED();
+}
+
+// GL_OES_matrix_palette
+void Context::currentPaletteMatrix(GLuint matrixpaletteindex)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::loadPaletteFromModelViewMatrix()
+{
+    UNIMPLEMENTED();
+}
+
+void Context::matrixIndexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::weightPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+    UNIMPLEMENTED();
+}
+
+// GL_OES_point_size_array
+void Context::pointSizePointer(GLenum type, GLsizei stride, const void *ptr)
+{
+    UNIMPLEMENTED();
+}
+
+// GL_OES_query_matrix
+GLbitfield Context::queryMatrixx(GLfixed *mantissa, GLint *exponent)
+{
+    UNIMPLEMENTED();
+    return 0;
+}
+
+// GL_OES_texture_cube_map
+void Context::getTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getTexGeniv(GLenum coord, GLenum pname, GLint *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::getTexGenxv(GLenum coord, GLenum pname, GLfixed *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::texGenf(GLenum coord, GLenum pname, GLfloat param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::texGenfv(GLenum coord, GLenum pname, const GLfloat *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::texGeni(GLenum coord, GLenum pname, GLint param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::texGeniv(GLenum coord, GLenum pname, const GLint *params)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::texGenx(GLenum coord, GLenum pname, GLfixed param)
+{
+    UNIMPLEMENTED();
+}
+
+void Context::texGenxv(GLenum coord, GLenum pname, const GLint *params)
+{
+    UNIMPLEMENTED();
+}
+
+}  // namespace gl
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context_gles_1_0_autogen.h
@@ -0,0 +1,129 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// 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.
+//
+// Context_gles_1_0_autogen.h: Creates a macro for interfaces in Context.
+
+#ifndef ANGLE_CONTEXT_GLES_1_0_AUTOGEN_H_
+#define ANGLE_CONTEXT_GLES_1_0_AUTOGEN_H_
+
+#define ANGLE_GLES1_CONTEXT_API                                                            \
+    void alphaFunc(AlphaTestFunc funcPacked, GLfloat ref);                                 \
+    void alphaFuncx(AlphaTestFunc funcPacked, GLfixed ref);                                \
+    void clearColorx(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);             \
+    void clearDepthx(GLfixed depth);                                                       \
+    void clientActiveTexture(GLenum texture);                                              \
+    void clipPlanef(GLenum p, const GLfloat *eqn);                                         \
+    void clipPlanex(GLenum plane, const GLfixed *equation);                                \
+    void color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);                 \
+    void color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);                \
+    void color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);                 \
+    void colorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer);       \
+    void depthRangex(GLfixed n, GLfixed f);                                                \
+    void disableClientState(GLenum array);                                                 \
+    void enableClientState(GLenum array);                                                  \
+    void fogf(GLenum pname, GLfloat param);                                                \
+    void fogfv(GLenum pname, const GLfloat *params);                                       \
+    void fogx(GLenum pname, GLfixed param);                                                \
+    void fogxv(GLenum pname, const GLfixed *param);                                        \
+    void frustumf(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);       \
+    void frustumx(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f);       \
+    void getClipPlanef(GLenum plane, GLfloat *equation);                                   \
+    void getClipPlanex(GLenum plane, GLfixed *equation);                                   \
+    void getFixedv(GLenum pname, GLfixed *params);                                         \
+    void getLightfv(GLenum light, GLenum pname, GLfloat *params);                          \
+    void getLightxv(GLenum light, GLenum pname, GLfixed *params);                          \
+    void getMaterialfv(GLenum face, GLenum pname, GLfloat *params);                        \
+    void getMaterialxv(GLenum face, GLenum pname, GLfixed *params);                        \
+    void getTexEnvfv(GLenum target, GLenum pname, GLfloat *params);                        \
+    void getTexEnviv(GLenum target, GLenum pname, GLint *params);                          \
+    void getTexEnvxv(GLenum target, GLenum pname, GLfixed *params);                        \
+    void getTexParameterxv(TextureType targetPacked, GLenum pname, GLfixed *params);       \
+    void lightModelf(GLenum pname, GLfloat param);                                         \
+    void lightModelfv(GLenum pname, const GLfloat *params);                                \
+    void lightModelx(GLenum pname, GLfixed param);                                         \
+    void lightModelxv(GLenum pname, const GLfixed *param);                                 \
+    void lightf(GLenum light, GLenum pname, GLfloat param);                                \
+    void lightfv(GLenum light, GLenum pname, const GLfloat *params);                       \
+    void lightx(GLenum light, GLenum pname, GLfixed param);                                \
+    void lightxv(GLenum light, GLenum pname, const GLfixed *params);                       \
+    void lineWidthx(GLfixed width);                                                        \
+    void loadIdentity();                                                                   \
+    void loadMatrixf(const GLfloat *m);                                                    \
+    void loadMatrixx(const GLfixed *m);                                                    \
+    void logicOp(GLenum opcode);                                                           \
+    void materialf(GLenum face, GLenum pname, GLfloat param);                              \
+    void materialfv(GLenum face, GLenum pname, const GLfloat *params);                     \
+    void materialx(GLenum face, GLenum pname, GLfixed param);                              \
+    void materialxv(GLenum face, GLenum pname, const GLfixed *param);                      \
+    void matrixMode(MatrixType modePacked);                                                \
+    void multMatrixf(const GLfloat *m);                                                    \
+    void multMatrixx(const GLfixed *m);                                                    \
+    void multiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);       \
+    void multiTexCoord4x(GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q);      \
+    void normal3f(GLfloat nx, GLfloat ny, GLfloat nz);                                     \
+    void normal3x(GLfixed nx, GLfixed ny, GLfixed nz);                                     \
+    void normalPointer(GLenum type, GLsizei stride, const void *pointer);                  \
+    void orthof(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);         \
+    void orthox(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f);         \
+    void pointParameterf(GLenum pname, GLfloat param);                                     \
+    void pointParameterfv(GLenum pname, const GLfloat *params);                            \
+    void pointParameterx(GLenum pname, GLfixed param);                                     \
+    void pointParameterxv(GLenum pname, const GLfixed *params);                            \
+    void pointSize(GLfloat size);                                                          \
+    void pointSizex(GLfixed size);                                                         \
+    void polygonOffsetx(GLfixed factor, GLfixed units);                                    \
+    void popMatrix();                                                                      \
+    void pushMatrix();                                                                     \
+    void rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);                          \
+    void rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z);                          \
+    void sampleCoveragex(GLclampx value, GLboolean invert);                                \
+    void scalef(GLfloat x, GLfloat y, GLfloat z);                                          \
+    void scalex(GLfixed x, GLfixed y, GLfixed z);                                          \
+    void shadeModel(GLenum mode);                                                          \
+    void texCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer);    \
+    void texEnvf(GLenum target, GLenum pname, GLfloat param);                              \
+    void texEnvfv(GLenum target, GLenum pname, const GLfloat *params);                     \
+    void texEnvi(GLenum target, GLenum pname, GLint param);                                \
+    void texEnviv(GLenum target, GLenum pname, const GLint *params);                       \
+    void texEnvx(GLenum target, GLenum pname, GLfixed param);                              \
+    void texEnvxv(GLenum target, GLenum pname, const GLfixed *params);                     \
+    void texParameterx(TextureType targetPacked, GLenum pname, GLfixed param);             \
+    void texParameterxv(TextureType targetPacked, GLenum pname, const GLfixed *params);    \
+    void translatef(GLfloat x, GLfloat y, GLfloat z);                                      \
+    void translatex(GLfixed x, GLfixed y, GLfixed z);                                      \
+    void vertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer);      \
+    /* GL_OES_draw_texture */                                                              \
+    void drawTexf(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);         \
+    void drawTexfv(const GLfloat *coords);                                                 \
+    void drawTexi(GLint x, GLint y, GLint z, GLint width, GLint height);                   \
+    void drawTexiv(const GLint *coords);                                                   \
+    void drawTexs(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height);         \
+    void drawTexsv(const GLshort *coords);                                                 \
+    void drawTexx(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height);         \
+    void drawTexxv(const GLfixed *coords);                                                 \
+    /* GL_OES_framebuffer_object */                                                        \
+    /* GL_OES_matrix_palette */                                                            \
+    void currentPaletteMatrix(GLuint matrixpaletteindex);                                  \
+    void loadPaletteFromModelViewMatrix();                                                 \
+    void matrixIndexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); \
+    void weightPointer(GLint size, GLenum type, GLsizei stride, const void *pointer);      \
+    /* GL_OES_point_size_array */                                                          \
+    void pointSizePointer(GLenum type, GLsizei stride, const void *pointer);               \
+    /* GL_OES_query_matrix */                                                              \
+    GLbitfield queryMatrixx(GLfixed *mantissa, GLint *exponent);                           \
+    /* GL_OES_texture_cube_map */                                                          \
+    void getTexGenfv(GLenum coord, GLenum pname, GLfloat *params);                         \
+    void getTexGeniv(GLenum coord, GLenum pname, GLint *params);                           \
+    void getTexGenxv(GLenum coord, GLenum pname, GLfixed *params);                         \
+    void texGenf(GLenum coord, GLenum pname, GLfloat param);                               \
+    void texGenfv(GLenum coord, GLenum pname, const GLfloat *params);                      \
+    void texGeni(GLenum coord, GLenum pname, GLint param);                                 \
+    void texGeniv(GLenum coord, GLenum pname, const GLint *params);                        \
+    void texGenx(GLenum coord, GLenum pname, GLfixed param);                               \
+    void texGenxv(GLenum coord, GLenum pname, const GLfixed *params);
+
+#endif  // ANGLE_CONTEXT_API_1_0_AUTOGEN_H_
--- a/gfx/angle/checkout/src/libANGLE/Display.cpp
+++ b/gfx/angle/checkout/src/libANGLE/Display.cpp
@@ -1044,16 +1044,19 @@ void Display::initDisplayExtensions()
     mDisplayExtensions.pixelFormatFloat                   = true;
 
     // Force EGL_KHR_get_all_proc_addresses on.
     mDisplayExtensions.getAllProcAddresses = true;
 
     // Enable program cache control since it is not back-end dependent.
     mDisplayExtensions.programCacheControl = true;
 
+    // Request extension is implemented in the ANGLE frontend
+    mDisplayExtensions.createContextExtensionsEnabled = true;
+
     mDisplayExtensionString = GenerateExtensionsString(mDisplayExtensions);
 }
 
 bool Display::isValidNativeWindow(EGLNativeWindowType window) const
 {
     return mImplementation->isValidNativeWindow(window);
 }
 
--- a/gfx/angle/checkout/src/libANGLE/Error.h
+++ b/gfx/angle/checkout/src/libANGLE/Error.h
@@ -157,17 +157,17 @@ class ANGLE_NO_DISCARD Error final
     Error(EGLint errorCode, std::string &&message);
     Error(EGLint errorCode, EGLint id, std::string &&message);
     inline Error(const Error &other);
     inline Error(Error &&other);
     inline ~Error() = default;
 
     // automatic error type conversion
     inline Error(gl::Error &&glErr);
-    inline Error(gl::Error glErr);
+    inline Error(const gl::Error &glErr);
 
     inline Error &operator=(const Error &other);
     inline Error &operator=(Error &&other);
 
     inline EGLint getCode() const;
     inline EGLint getID() const;
     inline bool isError() const;
 
--- a/gfx/angle/checkout/src/libANGLE/Error.inl
+++ b/gfx/angle/checkout/src/libANGLE/Error.inl
@@ -129,20 +129,20 @@ Error::Error(Error &&other)
 // automatic error type conversion
 Error::Error(gl::Error &&glErr)
     : mCode(EGL_BAD_ACCESS),
       mID(0),
       mMessage(std::move(glErr.mMessage))
 {
 }
 
-Error::Error(gl::Error glErr)
+Error::Error(const gl::Error &glErr)
     : mCode(EGL_BAD_ACCESS),
       mID(0),
-      mMessage(std::move(glErr.mMessage))
+      mMessage(glErr.mMessage.get())
 {
 }
 
 Error &Error::operator=(const Error &other)
 {
     mCode = other.mCode;
     mID = other.mID;
 
--- a/gfx/angle/checkout/src/libANGLE/ErrorStrings.h
+++ b/gfx/angle/checkout/src/libANGLE/ErrorStrings.h
@@ -11,56 +11,66 @@
 
 #define ERRMSG(name, message) \
     static const constexpr char *kError##name = static_cast<const char *>(message);
 #define ANGLE_VALIDATION_ERR(context, error, errorName) \
     context->handleError(error << kError##errorName)
 
 namespace gl
 {
+ERRMSG(BufferBoundForTransformFeedback, "Buffer is bound for transform feedback.");
 ERRMSG(BufferNotBound, "A buffer must be bound.");
 ERRMSG(CompressedTextureDimensionsMustMatchData,
        "Compressed texture dimensions must exactly match the dimensions of the data passed in.");
 ERRMSG(CompressedTexturesNotAttachable, "Compressed textures cannot be attached to a framebuffer.");
 ERRMSG(CubemapFacesEqualDimensions, "Each cubemap face must have equal width and height.");
 ERRMSG(CubemapIncomplete,
        "Texture is not cubemap complete. All cubemaps faces must be defined and be the same size.");
 ERRMSG(DefaultFramebufferInvalidAttachment,
        "Invalid attachment when the default framebuffer is bound.");
 ERRMSG(DefaultFramebufferTarget, "It is invalid to change default FBO's attachments");
 ERRMSG(DispatchIndirectBufferNotBound, "Dispatch indirect buffer must be bound.");
 ERRMSG(DrawBufferTypeMismatch,
        "Fragment shader output type does not match the bound framebuffer attachment type.");
+ERRMSG(ElementArrayBufferBoundForTransformFeedback,
+       "It is undefined behavior to use an element array buffer that is bound for transform "
+       "feedback.");
 ERRMSG(EnumNotSupported, "Enum is not currently supported.");
 ERRMSG(EnumRequiresGLES31, "Enum requires GLES 3.1");
 ERRMSG(ES31Required, "OpenGL ES 3.1 Required");
 ERRMSG(ES3Required, "OpenGL ES 3.0 Required.");
 ERRMSG(ExceedsMaxElement, "Element value exceeds maximum element index.");
 ERRMSG(ExpectedProgramName, "Expected a program name, but found a shader name.");
 ERRMSG(ExpectedShaderName, "Expected a shader name, but found a program name.");
 ERRMSG(ExtensionNotEnabled, "Extension is not enabled.");
 ERRMSG(FeedbackLoop, "Feedback loop formed between Framebuffer and active Texture.");
 ERRMSG(FramebufferIncompleteAttachment,
        "Attachment type must be compatible with attachment object.");
 ERRMSG(GenerateMipmapNotAllowed, "Texture format does not support mipmap generation.");
+ERRMSG(GeometryShaderExtensionNotEnabled, "GL_EXT_geometry_shader extension not enabled.");
+ERRMSG(GLES1Only, "GLES1-only function.");
+ERRMSG(IncompatibleDrawModeAgainstGeometryShader,
+       "Primitive mode is incompatible with the input primitive type of the geometry shader.");
 ERRMSG(IndexExceedsMaxActiveUniform, "Index exceeds program active uniform count.");
 ERRMSG(IndexExceedsMaxDrawBuffer, "Index exceeds MAX_DRAW_BUFFERS.");
 ERRMSG(IndexExceedsMaxVertexAttribute, "Index exceeds MAX_VERTEX_ATTRIBS.");
 ERRMSG(InsufficientBufferSize, "Insufficient buffer size.");
 ERRMSG(InsufficientVertexBufferSize, "Vertex buffer is not big enough for the draw call");
 ERRMSG(IntegerOverflow, "Integer overflow.");
 ERRMSG(InternalFormatRequiresTexture2DArray,
        "internalformat is an ETC2/EAC format and target is not GL_TEXTURE_2D_ARRAY.");
 ERRMSG(InvalidAttachment, "Invalid Attachment Type.");
 ERRMSG(InvalidBlendEquation, "Invalid blend equation.");
 ERRMSG(InvalidBlendFunction, "Invalid blend function.");
 ERRMSG(InvalidBorder, "Border must be 0.");
 ERRMSG(InvalidBufferTypes, "Invalid buffer target enum.");
 ERRMSG(InvalidBufferUsage, "Invalid buffer usage enum.");
 ERRMSG(InvalidClearMask, "Invalid mask bits.");
+ERRMSG(InvalidCombinedImageUnit,
+       "Specified unit must be in [GL_TEXTURE0, GL_TEXTURE0 + GL_MAX_COMBINED_IMAGE_UNITS)");
 ERRMSG(InvalidConstantColor,
        "CONSTANT_COLOR (or ONE_MINUS_CONSTANT_COLOR) and CONSTANT_ALPHA (or "
        "ONE_MINUS_CONSTANT_ALPHA) cannot be used together as source and destination factors in the "
        "blend function.");
 ERRMSG(InvalidCoverMode, "Invalid cover mode.");
 ERRMSG(InvalidCullMode, "Cull mode not recognized.");
 ERRMSG(InvalidDebugSeverity, "Invalid debug severity.");
 ERRMSG(InvalidDebugSource, "Invalid debug source.");
@@ -78,16 +88,18 @@ ERRMSG(InvalidFramebufferTarget, "Invali
 ERRMSG(InvalidFramebufferTextureLevel, "Mipmap level must be 0 when attaching a texture.");
 ERRMSG(InvalidFramebufferAttachmentParameter, "Invalid parameter name for framebuffer attachment.");
 ERRMSG(InvalidImageUnit,
        "Image unit cannot be greater than or equal to the value of MAX_IMAGE_UNITS.");
 ERRMSG(InvalidInternalFormat, "Invalid internal format.");
 ERRMSG(InvalidMatrixMode, "Invalid matrix mode.");
 ERRMSG(InvalidMemoryBarrierBit, "Invalid memory barrier bit.");
 ERRMSG(InvalidMipLevel, "Level of detail outside of range.");
+ERRMSG(InvalidMultitextureUnit,
+       "Specified unit must be in [GL_TEXTURE0, GL_TEXTURE0 + GL_MAX_TEXTURE_UNITS)");
 ERRMSG(InvalidName, "Invalid name.");
 ERRMSG(InvalidNameCharacters, "Name contains invalid characters.");
 ERRMSG(InvalidPname, "Invalid pname.");
 ERRMSG(InvalidPrecision, "Invalid or unsupported precision type.");
 ERRMSG(InvalidProgramName, "Program object expected.");
 ERRMSG(InvalidQueryId, "Invalid query Id.");
 ERRMSG(InvalidQueryTarget, "Invalid query target.");
 ERRMSG(InvalidQueryType, "Invalid query type.");
@@ -111,16 +123,18 @@ ERRMSG(InvalidTextureTarget, "Invalid or
 ERRMSG(InvalidTextureWrap, "Texture wrap mode not recognized.");
 ERRMSG(InvalidType, "Invalid type.");
 ERRMSG(InvalidTypePureInt, "Invalid type, should be integer");
 ERRMSG(InvalidUnpackAlignment, "Unpack alignment must be 1, 2, 4, or 8.");
 ERRMSG(InvalidVertexAttrSize, "Vertex attribute size must be 1, 2, 3, or 4.");
 ERRMSG(InvalidWidth, "Invalid width.");
 ERRMSG(InvalidWrapModeTexture, "Invalid wrap mode for texture type.");
 ERRMSG(LevelNotZero, "Texture level must be zero.");
+ERRMSG(MatrixStackOverflow, "Current matrix stack is full.");
+ERRMSG(MatrixStackUnderflow, "Current matrix stack has only a single matrix.");
 ERRMSG(MismatchedByteCountType, "Buffer size does not align with data type.");
 ERRMSG(MismatchedFormat, "Format must match internal format.");
 ERRMSG(MismatchedTargetAndFormat, "Invalid texture target and format combination.");
 ERRMSG(MismatchedTypeAndFormat, "Invalid format and type combination.");
 ERRMSG(MismatchedVariableProgram, "Variable is not part of the current program.");
 ERRMSG(MissingReadAttachment, "Missing read attachment.");
 ERRMSG(MustHaveElementArrayBinding, "Must have element array buffer binding.");
 ERRMSG(NameBeginsWithGL, "Attributes that begin with 'gl_' are not allowed.");
@@ -130,30 +144,36 @@ ERRMSG(NegativeCount, "Negative count.")
 ERRMSG(NegativeLength, "Negative length.");
 ERRMSG(NegativeMaxCount, "Negative maxcount.");
 ERRMSG(NegativeOffset, "Negative offset.");
 ERRMSG(NegativePrimcount, "Primcount must be greater than or equal to zero.");
 ERRMSG(NegativeSize, "Cannot have negative height or width.");
 ERRMSG(NegativeStart, "Cannot have negative start.");
 ERRMSG(NegativeStride, "Cannot have negative stride.");
 ERRMSG(NoActiveComputeShaderStage, "No active compute shader stage in this program.");
+ERRMSG(NoActiveGeometryShaderStage, "No active geometry shader stage in this program.");
 ERRMSG(NoActiveProgramWithComputeShader, "No active program for the compute shader stage.");
 ERRMSG(NoSuchPath, "No such path object.");
 ERRMSG(NoTransformFeedbackOutputVariables,
-    "The active program has specified no output variables to record.");
+       "The active program has specified no output variables to record.");
 ERRMSG(NoZeroDivisor, "At least one enabled attribute must have a divisor of zero.");
 ERRMSG(NVFenceNotSupported, "GL_NV_fence is not supported");
 ERRMSG(ObjectNotGenerated, "Object cannot be used because it has not been generated.");
 ERRMSG(OffsetMustBeMultipleOfType, "Offset must be a multiple of the passed in datatype.");
 ERRMSG(OffsetMustBeMultipleOfUint,
        "Offset must be a multiple of the size, in basic machine units, of uint");
 ERRMSG(OutsideOfBounds, "Parameter outside of bounds.");
 ERRMSG(ParamOverflow, "The provided parameters overflow with the provided buffer.");
 ERRMSG(PixelDataNotNull, "Pixel data must be null.");
 ERRMSG(PixelDataNull, "Pixel data cannot be null.");
+ERRMSG(PixelPackBufferBoundForTransformFeedback,
+       "It is undefined behavior to use a pixel pack buffer that is bound for transform feedback.");
+ERRMSG(
+    PixelUnpackBufferBoundForTransformFeedback,
+    "It is undefined behavior to use a pixel unpack buffer that is bound for transform feedback.");
 ERRMSG(ProgramDoesNotExist, "Program doesn't exist.");
 ERRMSG(ProgramNotBound, "A program must be bound.");
 ERRMSG(ProgramNotLinked, "Program not linked.");
 ERRMSG(QueryActive, "Query is active.");
 ERRMSG(QueryExtensionNotEnabled, "Query extension not enabled.");
 ERRMSG(ReadBufferNone, "Read buffer is GL_NONE.");
 ERRMSG(RenderbufferNotBound, "A renderbuffer must be bound.");
 ERRMSG(ResourceMaxTextureSize, "Desired resource size is greater than max texture size.");
@@ -163,25 +183,33 @@ ERRMSG(ShaderToDetachMustBeAttached,
        "Shader to be detached must be currently attached to the program.");
 ERRMSG(SourceTextureTooSmall, "The specified dimensions are outside of the bounds of the texture.");
 ERRMSG(StencilReferenceMaskOrMismatch,
        "Stencil reference and mask values must be the same for front facing and back facing "
        "triangles.");
 ERRMSG(StrideMustBeMultipleOfType, "Stride must be a multiple of the passed in datatype.");
 ERRMSG(TextureNotBound, "A texture must be bound.");
 ERRMSG(TextureNotPow2, "The texture is a non-power-of-two texture.");
+ERRMSG(TransformFeedbackBufferDoubleBound,
+       "A transform feedback buffer that would be written to is also bound to a "
+       "non-transform-feedback target, which would cause undefined behavior.");
+ERRMSG(TransformFeedbackBufferTooSmall, "Not enough space in bound transform feedback buffers.");
 ERRMSG(TransformFeedbackDoesNotExist, "Transform feedback object that does not exist.");
 ERRMSG(TypeMismatch,
        "Passed in texture target and format must match the one originally used to define the "
        "texture.");
 ERRMSG(TypeNotUnsignedShortByte, "Only UNSIGNED_SHORT and UNSIGNED_BYTE types are supported.");
+ERRMSG(UniformBufferBoundForTransformFeedback,
+       "It is undefined behavior to use an uniform buffer that is bound for transform feedback.");
 ERRMSG(UniformSizeMismatch, "Uniform size does not match uniform method.");
 ERRMSG(UnknownParameter, "Unknown parameter value.");
 ERRMSG(VertexArrayNoBuffer, "An enabled vertex array has no buffer.");
 ERRMSG(VertexArrayNoBufferPointer, "An enabled vertex array has no buffer and no pointer.");
+ERRMSG(VertexBufferBoundForTransformFeedback,
+       "It is undefined behavior to use a vertex buffer that is bound for transform feedback.");
 ERRMSG(VertexShaderTypeMismatch,
        "Vertex shader input type does not match the type of the bound vertex attribute.")
 ERRMSG(ViewportNegativeSize, "Viewport size cannot be negative.");
 ERRMSG(Webgl2NameLengthLimitExceeded, "Location lengths must not be greater than 1024 characters.");
 ERRMSG(WebglBindAttribLocationReservedPrefix,
        "Attributes that begin with 'webgl_', or '_webgl_' are not allowed.");
 ERRMSG(WebglNameLengthLimitExceeded,
        "Location name lengths must not be greater than 256 characters.");
--- a/gfx/angle/checkout/src/libANGLE/Framebuffer.cpp
+++ b/gfx/angle/checkout/src/libANGLE/Framebuffer.cpp
@@ -85,17 +85,17 @@ bool CheckAttachmentCompleteness(const C
         }
 
         // ES3 specifies that cube map texture attachments must be cube complete.
         // This language is missing from the ES2 spec, but we enforce it here because some
         // desktop OpenGL drivers also enforce this validation.
         // TODO(jmadill): Check if OpenGL ES2 drivers enforce cube completeness.
         const Texture *texture = attachment.getTexture();
         ASSERT(texture);
-        if (texture->getTarget() == GL_TEXTURE_CUBE_MAP &&
+        if (texture->getType() == TextureType::CubeMap &&
             !texture->getTextureState().isCubeComplete())
         {
             return false;
         }
 
         if (!texture->getImmutableFormat())
         {
             GLuint attachmentMipLevel = static_cast<GLuint>(attachment.mipLevel());
@@ -976,38 +976,49 @@ bool Framebuffer::usingExtendedDrawBuffe
 void Framebuffer::invalidateCompletenessCache()
 {
     if (mId != 0)
     {
         mCachedStatus.reset();
     }
 }
 
-GLenum Framebuffer::checkStatus(const Context *context)
+Error Framebuffer::checkStatus(const Context *context, GLenum *statusOut)
 {
     // The default framebuffer is always complete except when it is surfaceless in which
     // case it is always unsupported. We return early because the default framebuffer may
     // not be subject to the same rules as application FBOs. ie, it could have 0x0 size.
     if (mId == 0)
     {
         ASSERT(mCachedStatus.valid());
         ASSERT(mCachedStatus.value() == GL_FRAMEBUFFER_COMPLETE ||
                mCachedStatus.value() == GL_FRAMEBUFFER_UNDEFINED_OES);
-        return mCachedStatus.value();
+        *statusOut = mCachedStatus.value();
+        return NoError();
     }
 
     if (hasAnyDirtyBit() || !mCachedStatus.valid())
     {
-        mCachedStatus = checkStatusImpl(context);
+        mCachedStatus = checkStatusWithGLFrontEnd(context);
+
+        if (mCachedStatus.value() == GL_FRAMEBUFFER_COMPLETE)
+        {
+            ANGLE_TRY(syncState(context));
+            if (!mImpl->checkStatus(context))
+            {
+                mCachedStatus = GL_FRAMEBUFFER_UNSUPPORTED;
+            }
+        }
     }
 
-    return mCachedStatus.value();
+    *statusOut = mCachedStatus.value();
+    return NoError();
 }
 
-GLenum Framebuffer::checkStatusImpl(const Context *context)
+GLenum Framebuffer::checkStatusWithGLFrontEnd(const Context *context)
 {
     const ContextState &state = context->getContextState();
 
     ASSERT(mId != 0);
 
     bool hasAttachments = false;
     Optional<unsigned int> colorbufferSize;
     Optional<int> samples;
@@ -1194,22 +1205,16 @@ GLenum Framebuffer::checkStatusImpl(cons
     if (state.getExtensions().webglCompatibility)
     {
         if (!mState.colorAttachmentsAreUniqueImages())
         {
             return GL_FRAMEBUFFER_UNSUPPORTED;
         }
     }
 
-    syncState(context);
-    if (!mImpl->checkStatus(context))
-    {
-        return GL_FRAMEBUFFER_UNSUPPORTED;
-    }
-
     return GL_FRAMEBUFFER_COMPLETE;
 }
 
 Error Framebuffer::discard(const Context *context, size_t count, const GLenum *attachments)
 {
     // Back-ends might make the contents of the FBO undefined. In WebGL 2.0, invalidate operations
     // can be no-ops, so we should probably do that to ensure consistency.
     // TODO(jmadill): WebGL behaviour, and robust resource init behaviour without WebGL.
@@ -1282,162 +1287,113 @@ Error Framebuffer::invalidateSub(const C
 Error Framebuffer::clear(const Context *context, GLbitfield mask)
 {
     const auto &glState = context->getGLState();
     if (glState.isRasterizerDiscardEnabled())
     {
         return NoError();
     }
 
-    const auto &blend        = glState.getBlendState();
-    const auto &depthStencil = glState.getDepthStencilState();
-
-    bool color   = (mask & GL_COLOR_BUFFER_BIT) != 0 && !IsColorMaskedOut(blend);
-    bool depth   = (mask & GL_DEPTH_BUFFER_BIT) != 0 && !IsDepthMaskedOut(depthStencil);
-    bool stencil = (mask & GL_STENCIL_BUFFER_BIT) != 0 && !IsStencilMaskedOut(depthStencil);
-
-    if (partialClearNeedsInit(context, color, depth, stencil))
-    {
-        ANGLE_TRY(ensureDrawAttachmentsInitialized(context));
-    }
-
     ANGLE_TRY(mImpl->clear(context, mask));
 
-    if (glState.isRobustResourceInitEnabled())
-    {
-        markDrawAttachmentsInitialized(color, depth, stencil);
-    }
-
     return NoError();
 }
 
 Error Framebuffer::clearBufferfv(const Context *context,
                                  GLenum buffer,
                                  GLint drawbuffer,
                                  const GLfloat *values)
 {
     if (context->getGLState().isRasterizerDiscardEnabled() ||
         IsClearBufferMaskedOut(context, buffer))
     {
         return NoError();
     }
 
-    if (partialBufferClearNeedsInit(context, buffer))
-    {
-        ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer));
-    }
-
     ANGLE_TRY(mImpl->clearBufferfv(context, buffer, drawbuffer, values));
 
-    if (context->isRobustResourceInitEnabled())
-    {
-        markBufferInitialized(buffer, drawbuffer);
-    }
     return NoError();
 }
 
 Error Framebuffer::clearBufferuiv(const Context *context,
                                   GLenum buffer,
                                   GLint drawbuffer,
                                   const GLuint *values)
 {
     if (context->getGLState().isRasterizerDiscardEnabled() ||
         IsClearBufferMaskedOut(context, buffer))
     {
         return NoError();
     }
 
-    if (partialBufferClearNeedsInit(context, buffer))
-    {
-        ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer));
-    }
-
     ANGLE_TRY(mImpl->clearBufferuiv(context, buffer, drawbuffer, values));
 
-    if (context->isRobustResourceInitEnabled())
-    {
-        markBufferInitialized(buffer, drawbuffer);
-    }
     return NoError();
 }
 
 Error Framebuffer::clearBufferiv(const Context *context,
                                  GLenum buffer,
                                  GLint drawbuffer,
                                  const GLint *values)
 {
     if (context->getGLState().isRasterizerDiscardEnabled() ||
         IsClearBufferMaskedOut(context, buffer))
     {
         return NoError();
     }
 
-    if (partialBufferClearNeedsInit(context, buffer))
-    {
-        ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer));
-    }
-
     ANGLE_TRY(mImpl->clearBufferiv(context, buffer, drawbuffer, values));
 
-    if (context->isRobustResourceInitEnabled())
-    {
-        markBufferInitialized(buffer, drawbuffer);
-    }
     return NoError();
 }
 
 Error Framebuffer::clearBufferfi(const Context *context,
                                  GLenum buffer,
                                  GLint drawbuffer,
                                  GLfloat depth,
                                  GLint stencil)
 {
     if (context->getGLState().isRasterizerDiscardEnabled() ||
         IsClearBufferMaskedOut(context, buffer))
     {
         return NoError();
     }
 
-    if (partialBufferClearNeedsInit(context, buffer))
-    {
-        ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer));
-    }
-
     ANGLE_TRY(mImpl->clearBufferfi(context, buffer, drawbuffer, depth, stencil));
 
-    if (context->isRobustResourceInitEnabled())
-    {
-        markBufferInitialized(buffer, drawbuffer);
-    }
     return NoError();
 }
 
-GLenum Framebuffer::getImplementationColorReadFormat(const Context *context) const
+Error Framebuffer::getImplementationColorReadFormat(const Context *context, GLenum *formatOut)
 {
-    return mImpl->getImplementationColorReadFormat(context);
+    ANGLE_TRY(syncState(context));
+    *formatOut = mImpl->getImplementationColorReadFormat(context);
+    return NoError();
 }
 
-GLenum Framebuffer::getImplementationColorReadType(const Context *context) const
+Error Framebuffer::getImplementationColorReadType(const Context *context, GLenum *typeOut)
 {
-    return mImpl->getImplementationColorReadType(context);
+    ANGLE_TRY(syncState(context));
+    *typeOut = mImpl->getImplementationColorReadType(context);
+    return NoError();
 }
 
 Error Framebuffer::readPixels(const Context *context,
                               const Rectangle &area,
                               GLenum format,
                               GLenum type,
                               void *pixels)
 {
     ANGLE_TRY(ensureReadAttachmentInitialized(context, GL_COLOR_BUFFER_BIT));
     ANGLE_TRY(mImpl->readPixels(context, area, format, type, pixels));
 
     Buffer *unpackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
     if (unpackBuffer)
     {
-        unpackBuffer->onPixelUnpack();
+        unpackBuffer->onPixelPack(context);
     }
 
     return NoError();
 }
 
 Error Framebuffer::blit(const Context *context,
                         const Rectangle &sourceArea,
                         const Rectangle &destArea,
@@ -1472,28 +1428,28 @@ Error Framebuffer::blit(const Context *c
     ANGLE_TRY(sourceFBO->ensureReadAttachmentInitialized(context, blitMask));
 
     // TODO(jmadill): Only clear if not the full FBO dimensions, and only specified bitmask.
     ANGLE_TRY(ensureDrawAttachmentsInitialized(context));
 
     return mImpl->blit(context, sourceArea, destArea, blitMask, filter);
 }
 
-int Framebuffer::getSamples(const Context *context)
+Error Framebuffer::getSamples(const Context *context, int *samplesOut)
 {
-    if (complete(context))
-    {
-        return getCachedSamples(context);
-    }
-
-    return 0;
+    bool completeness = false;
+    ANGLE_TRY(isComplete(context, &completeness));
+    *samplesOut = completeness ? getCachedSamples(context) : 0;
+    return NoError();
 }
 
 int Framebuffer::getCachedSamples(const Context *context)
 {
+    ASSERT(mCachedStatus.valid() && mCachedStatus.value() == GL_FRAMEBUFFER_COMPLETE);
+
     // For a complete framebuffer, all attachments must have the same sample count.
     // In this case return the first nonzero sample size.
     const auto *firstNonNullAttachment = mState.getFirstNonNullAttachment();
     if (firstNonNullAttachment)
     {
         ASSERT(firstNonNullAttachment->isAttached());
         return firstNonNullAttachment->getSamples();
     }
@@ -1768,41 +1724,50 @@ void Framebuffer::updateAttachment(const
                                    GLuint baseViewIndex,
                                    GLenum multiviewLayout,
                                    const GLint *viewportOffsets)
 {
     attachment->attach(context, type, binding, textureIndex, resource, numViews, baseViewIndex,
                        multiviewLayout, viewportOffsets);
     mDirtyBits.set(dirtyBit);
     mState.mResourceNeedsInit.set(dirtyBit, attachment->initState() == InitState::MayNeedInit);
-    onDirtyBinding->bind(resource);
+    onDirtyBinding->bind(resource ? resource->getSubject() : nullptr);
+
+    invalidateCompletenessCache();
 }
 
 void Framebuffer::resetAttachment(const Context *context, GLenum binding)
 {
     setAttachment(context, GL_NONE, binding, ImageIndex::MakeInvalid(), nullptr);
 }
 
-void Framebuffer::syncState(const Context *context)
+Error Framebuffer::syncState(const Context *context)
 {
     if (mDirtyBits.any())
     {
-        mImpl->syncState(context, mDirtyBits);
+        mDirtyBitsGuard = mDirtyBits;
+        ANGLE_TRY(mImpl->syncState(context, mDirtyBits));
         mDirtyBits.reset();
-        if (mId != 0)
-        {
-            mCachedStatus.reset();
-        }
+        mDirtyBitsGuard.reset();
     }
+    return NoError();
 }
 
 void Framebuffer::onSubjectStateChange(const Context *context,
                                        angle::SubjectIndex index,
                                        angle::SubjectMessage message)
 {
+    if (message == angle::SubjectMessage::DEPENDENT_DIRTY_BITS)
+    {
+        ASSERT(!mDirtyBitsGuard.valid() || mDirtyBitsGuard.value().test(index));
+        mDirtyBits.set(index);
+        context->getGLState().setFramebufferDirty(this);
+        return;
+    }
+
     // Only reset the cached status if this is not the default framebuffer.  The default framebuffer
     // will still use this channel to mark itself dirty.
     if (mId != 0)
     {
         // TOOD(jmadill): Make this only update individual attachments to do less work.
         mCachedStatus.reset();
     }
 
@@ -1822,24 +1787,22 @@ FramebufferAttachment *Framebuffer::getA
             return &mState.mStencilAttachment;
         default:
             size_t colorIndex = (index - DIRTY_BIT_COLOR_ATTACHMENT_0);
             ASSERT(colorIndex < mState.mColorAttachments.size());
             return &mState.mColorAttachments[colorIndex];
     }
 }
 
-bool Framebuffer::complete(const Context *context)
+Error Framebuffer::isComplete(const Context *context, bool *completeOut)
 {
-    return (checkStatus(context) == GL_FRAMEBUFFER_COMPLETE);
-}
-
-bool Framebuffer::cachedComplete() const
-{
-    return (mCachedStatus.valid() && mCachedStatus == GL_FRAMEBUFFER_COMPLETE);
+    GLenum status = GL_NONE;
+    ANGLE_TRY(checkStatus(context, &status));
+    *completeOut = (status == GL_FRAMEBUFFER_COMPLETE);
+    return NoError();
 }
 
 bool Framebuffer::formsRenderingFeedbackLoopWith(const State &state) const
 {
     const Program *program = state.getProgram();
 
     // TODO(jmadill): Default framebuffer feedback loops.
     if (mId == 0)
@@ -1870,28 +1833,34 @@ bool Framebuffer::formsRenderingFeedback
     if (depth && depth->type() == GL_TEXTURE && dsState.depthTest && dsState.depthMask)
     {
         if (program->samplesFromTexture(state, depth->id()))
         {
             return true;
         }
     }
 
-    // Note: we assume the front and back masks are the same for WebGL.
     const FramebufferAttachment *stencil = getStencilbuffer();
-    ASSERT(dsState.stencilBackWritemask == dsState.stencilWritemask);
-    if (stencil && stencil->type() == GL_TEXTURE && dsState.stencilTest &&
-        dsState.stencilWritemask != 0)
+    if (dsState.stencilTest && stencil)
     {
-        // Skip the feedback loop check if depth/stencil point to the same resource.
-        if (!depth || *stencil != *depth)
+        GLuint stencilSize = stencil->getStencilSize();
+        ASSERT(stencilSize <= 8);
+        GLuint maxStencilValue = (1 << stencilSize) - 1;
+        // We assume the front and back masks are the same for WebGL.
+        ASSERT((dsState.stencilBackWritemask & maxStencilValue) ==
+               (dsState.stencilWritemask & maxStencilValue));
+        if (stencil->type() == GL_TEXTURE && dsState.stencilWritemask != 0)
         {
-            if (program->samplesFromTexture(state, stencil->id()))
+            // Skip the feedback loop check if depth/stencil point to the same resource.
+            if (!depth || *stencil != *depth)
             {
-                return true;
+                if (program->samplesFromTexture(state, stencil->id()))
+                {
+                    return true;
+                }
             }
         }
     }
 
     return false;
 }
 
 bool Framebuffer::formsCopyingFeedbackLoopWith(GLuint copyTextureID,
@@ -1940,45 +1909,38 @@ bool Framebuffer::getDefaultFixedSampleL
 {
     return mState.getDefaultFixedSampleLocations();
 }
 
 void Framebuffer::setDefaultWidth(GLint defaultWidth)
 {
     mState.mDefaultWidth = defaultWidth;
     mDirtyBits.set(DIRTY_BIT_DEFAULT_WIDTH);
+    invalidateCompletenessCache();
 }
 
 void Framebuffer::setDefaultHeight(GLint defaultHeight)
 {
     mState.mDefaultHeight = defaultHeight;
     mDirtyBits.set(DIRTY_BIT_DEFAULT_HEIGHT);
+    invalidateCompletenessCache();
 }
 
 void Framebuffer::setDefaultSamples(GLint defaultSamples)
 {
     mState.mDefaultSamples = defaultSamples;
     mDirtyBits.set(DIRTY_BIT_DEFAULT_SAMPLES);
+    invalidateCompletenessCache();
 }
 
 void Framebuffer::setDefaultFixedSampleLocations(bool defaultFixedSampleLocations)
 {
     mState.mDefaultFixedSampleLocations = defaultFixedSampleLocations;
     mDirtyBits.set(DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS);
-}
-
-// TODO(jmadill): Remove this kludge.
-GLenum Framebuffer::checkStatus(const ValidationContext *context)
-{
-    return checkStatus(static_cast<const Context *>(context));
-}
-
-int Framebuffer::getSamples(const ValidationContext *context)
-{
-    return getSamples(static_cast<const Context *>(context));
+    invalidateCompletenessCache();
 }
 
 GLsizei Framebuffer::getNumViews() const
 {
     return mState.getNumViews();
 }
 
 GLint Framebuffer::getBaseViewIndex() const
@@ -1991,16 +1953,73 @@ const std::vector<Offset> *Framebuffer::
     return mState.getViewportOffsets();
 }
 
 GLenum Framebuffer::getMultiviewLayout() const
 {
     return mState.getMultiviewLayout();
 }
 
+Error Framebuffer::ensureClearAttachmentsInitialized(const Context *context, GLbitfield mask)
+{
+    const auto &glState = context->getGLState();
+    if (!context->isRobustResourceInitEnabled() || glState.isRasterizerDiscardEnabled())
+    {
+        return NoError();
+    }
+
+    const BlendState &blend               = glState.getBlendState();
+    const DepthStencilState &depthStencil = glState.getDepthStencilState();
+
+    bool color   = (mask & GL_COLOR_BUFFER_BIT) != 0 && !IsColorMaskedOut(blend);
+    bool depth   = (mask & GL_DEPTH_BUFFER_BIT) != 0 && !IsDepthMaskedOut(depthStencil);
+    bool stencil = (mask & GL_STENCIL_BUFFER_BIT) != 0 && !IsStencilMaskedOut(depthStencil);
+
+    if (!color && !depth && !stencil)
+    {
+        return NoError();
+    }
+
+    if (partialClearNeedsInit(context, color, depth, stencil))
+    {
+        ANGLE_TRY(ensureDrawAttachmentsInitialized(context));
+    }
+
+    // If the impl encounters an error during a a full (non-partial) clear, the attachments will
+    // still be marked initialized. This simplifies design, allowing this method to be called before
+    // the clear.
+    markDrawAttachmentsInitialized(color, depth, stencil);
+
+    return NoError();
+}
+
+Error Framebuffer::ensureClearBufferAttachmentsInitialized(const Context *context,
+                                                           GLenum buffer,
+                                                           GLint drawbuffer)
+{
+    if (!context->isRobustResourceInitEnabled() ||
+        context->getGLState().isRasterizerDiscardEnabled() ||
+        IsClearBufferMaskedOut(context, buffer))
+    {
+        return NoError();
+    }
+
+    if (partialBufferClearNeedsInit(context, buffer))
+    {
+        ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer));
+    }
+
+    // If the impl encounters an error during a a full (non-partial) clear, the attachments will
+    // still be marked initialized. This simplifies design, allowing this method to be called before
+    // the clear.
+    markBufferInitialized(buffer, drawbuffer);
+
+    return NoError();
+}
+
 Error Framebuffer::ensureDrawAttachmentsInitialized(const Context *context)
 {
     if (!context->isRobustResourceInitEnabled())
     {
         return NoError();
     }
 
     // Note: we don't actually filter by the draw attachment enum. Just init everything.
--- a/gfx/angle/checkout/src/libANGLE/Framebuffer.h
+++ b/gfx/angle/checkout/src/libANGLE/Framebuffer.h
@@ -13,18 +13,18 @@
 #include <vector>
 
 #include "common/Optional.h"
 #include "common/angleutils.h"
 #include "libANGLE/Constants.h"
 #include "libANGLE/Debug.h"
 #include "libANGLE/Error.h"
 #include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Observer.h"
 #include "libANGLE/RefCountObject.h"
-#include "libANGLE/signal_utils.h"
 
 namespace rx
 {
 class GLImplFactory;
 class FramebufferImpl;
 class RenderbufferImpl;
 class SurfaceImpl;
 }
@@ -39,17 +39,16 @@ namespace gl
 {
 class Context;
 class ContextState;
 class Framebuffer;
 class Renderbuffer;
 class State;
 class Texture;
 class TextureCapsMap;
-class ValidationContext;
 struct Caps;
 struct Extensions;
 struct ImageIndex;
 struct Rectangle;
 
 class FramebufferState final : angle::NonCopyable
 {
   public:
@@ -128,17 +127,17 @@ class FramebufferState final : angle::No
     FramebufferAttachment mWebGLDepthAttachment;
     FramebufferAttachment mWebGLStencilAttachment;
     bool mWebGLDepthStencilConsistent;
 
     // Tracks if we need to initialize the resources for each attachment.
     angle::BitSet<IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS + 2> mResourceNeedsInit;
 };
 
-class Framebuffer final : public LabeledObject, public angle::ObserverInterface
+class Framebuffer final : public angle::ObserverInterface, public LabeledObject
 {
   public:
     // Constructor to build application-defined framebuffers
     Framebuffer(const Caps &caps, rx::GLImplFactory *factory, GLuint id);
     // Constructor to build default framebuffers for a surface
     Framebuffer(const egl::Display *display, egl::Surface *surface);
     // Constructor to build a fake default framebuffer when surfaceless
     Framebuffer(rx::GLImplFactory *factory);
@@ -210,43 +209,38 @@ class Framebuffer final : public Labeled
 
     size_t getNumColorBuffers() const;
     bool hasDepth() const;
     bool hasStencil() const;
 
     bool usingExtendedDrawBuffers() const;
 
     // This method calls checkStatus.
-    int getSamples(const Context *context);
+    Error getSamples(const Context *context, int *samplesOut);
 
     Error getSamplePosition(size_t index, GLfloat *xy) const;
 
     GLint getDefaultWidth() const;
     GLint getDefaultHeight() const;
     GLint getDefaultSamples() const;
     bool getDefaultFixedSampleLocations() const;
     void setDefaultWidth(GLint defaultWidth);
     void setDefaultHeight(GLint defaultHeight);
     void setDefaultSamples(GLint defaultSamples);
     void setDefaultFixedSampleLocations(bool defaultFixedSampleLocations);
 
     void invalidateCompletenessCache();
 
-    GLenum checkStatus(const Context *context);
-
-    // TODO(jmadill): Remove this kludge.
-    GLenum checkStatus(const ValidationContext *context);
-    int getSamples(const ValidationContext *context);
+    Error checkStatus(const Context *context, GLenum *statusOut);
 
     // For when we don't want to check completeness in getSamples().
     int getCachedSamples(const Context *context);
 
     // Helper for checkStatus == GL_FRAMEBUFFER_COMPLETE.
-    bool complete(const Context *context);
-    bool cachedComplete() const;
+    Error isComplete(const Context *context, bool *completeOut);
 
     bool hasValidDepthStencil() const;
 
     Error discard(const Context *context, size_t count, const GLenum *attachments);
     Error invalidate(const Context *context, size_t count, const GLenum *attachments);
     Error invalidateSub(const Context *context,
                         size_t count,
                         const GLenum *attachments,
@@ -266,18 +260,20 @@ class Framebuffer final : public Labeled
                         GLint drawbuffer,
                         const GLint *values);
     Error clearBufferfi(const Context *context,
                         GLenum buffer,
                         GLint drawbuffer,
                         GLfloat depth,
                         GLint stencil);
 
-    GLenum getImplementationColorReadFormat(const Context *context) const;
-    GLenum getImplementationColorReadType(const Context *context) const;
+    // These two methods call syncState() internally.
+    Error getImplementationColorReadFormat(const Context *context, GLenum *formatOut);
+    Error getImplementationColorReadType(const Context *context, GLenum *typeOut);
+
     Error readPixels(const Context *context,
                      const Rectangle &area,
                      GLenum format,
                      GLenum type,
                      void *pixels);
 
     Error blit(const Context *context,
                const Rectangle &sourceArea,
@@ -300,42 +296,46 @@ class Framebuffer final : public Labeled
         DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS,
         DIRTY_BIT_UNKNOWN,
         DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN
     };
 
     using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
     bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
 
-    void syncState(const Context *context);
+    Error syncState(const Context *context);
 
     // Observer implementation
     void onSubjectStateChange(const Context *context,
                               angle::SubjectIndex index,
                               angle::SubjectMessage message) override;
 
     bool formsRenderingFeedbackLoopWith(const State &state) const;
     bool formsCopyingFeedbackLoopWith(GLuint copyTextureID,
                                       GLint copyTextureLevel,
                                       GLint copyTextureLayer) const;
 
+    Error ensureClearAttachmentsInitialized(const Context *context, GLbitfield mask);
+    Error ensureClearBufferAttachmentsInitialized(const Context *context,
+                                                  GLenum buffer,
+                                                  GLint drawbuffer);
     Error ensureDrawAttachmentsInitialized(const Context *context);
     Error ensureReadAttachmentInitialized(const Context *context, GLbitfield blitMask);
     Box getDimensions() const;
 
     bool hasTextureAttachment(const Texture *texture) const;
 
   private:
     bool detachResourceById(const Context *context, GLenum resourceType, GLuint resourceId);
     bool detachMatchingAttachment(const Context *context,
                                   FramebufferAttachment *attachment,
                                   GLenum matchType,
                                   GLuint matchId,
                                   size_t dirtyBit);
-    GLenum checkStatusImpl(const Context *context);
+    GLenum checkStatusWithGLFrontEnd(const Context *context);
     void setAttachment(const Context *context,
                        GLenum type,
                        GLenum binding,
                        const ImageIndex &textureIndex,
                        FramebufferAttachmentObject *resource,
                        GLsizei numViews,
                        GLuint baseViewIndex,
                        GLenum multiviewLayout,
@@ -386,15 +386,19 @@ class Framebuffer final : public Labeled
 
     Optional<GLenum> mCachedStatus;
     std::vector<angle::ObserverBinding> mDirtyColorAttachmentBindings;
     angle::ObserverBinding mDirtyDepthAttachmentBinding;
     angle::ObserverBinding mDirtyStencilAttachmentBinding;
 
     DirtyBits mDirtyBits;
 
+    // The dirty bits guard is checked when we get a dependent state change message. We verify that
+    // we don't set a dirty bit that isn't already set, when inside the dirty bits syncState.
+    Optional<DirtyBits> mDirtyBitsGuard;
+
     // A cache of attached textures for quick validation of feedback loops.
     mutable Optional<std::set<const FramebufferAttachmentObject *>> mAttachedTextures;
 };
 
 }  // namespace gl
 
 #endif  // LIBANGLE_FRAMEBUFFER_H_
--- a/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.cpp
+++ b/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.cpp
@@ -177,42 +177,42 @@ void FramebufferAttachment::attach(const
         mResource->onDetach(context);
     }
 
     mResource = resource;
 }
 
 GLuint FramebufferAttachment::getRedSize() const
 {
-    return getSize().empty() ? 0 : getFormat().info->redBits;
+    return getFormat().info->redBits;
 }
 
 GLuint FramebufferAttachment::getGreenSize() const
 {
-    return getSize().empty() ? 0 : getFormat().info->greenBits;
+    return getFormat().info->greenBits;
 }
 
 GLuint FramebufferAttachment::getBlueSize() const
 {
-    return getSize().empty() ? 0 : getFormat().info->blueBits;
+    return getFormat().info->blueBits;
 }
 
 GLuint FramebufferAttachment::getAlphaSize() const
 {
-    return getSize().empty() ? 0 : getFormat().info->alphaBits;
+    return getFormat().info->alphaBits;
 }
 
 GLuint FramebufferAttachment::getDepthSize() const
 {
-    return getSize().empty() ? 0 : getFormat().info->depthBits;
+    return getFormat().info->depthBits;
 }
 
 GLuint FramebufferAttachment::getStencilSize() const
 {
-    return getSize().empty() ? 0 : getFormat().info->stencilBits;
+    return getFormat().info->stencilBits;
 }
 
 GLenum FramebufferAttachment::getComponentType() const
 {
     return getFormat().info->componentType;
 }
 
 GLenum FramebufferAttachment::getColorEncoding() const
@@ -226,22 +226,22 @@ GLuint FramebufferAttachment::id() const
 }
 
 const ImageIndex &FramebufferAttachment::getTextureImageIndex() const
 {
     ASSERT(type() == GL_TEXTURE);
     return mTarget.textureIndex();
 }
 
-GLenum FramebufferAttachment::cubeMapFace() const
+TextureTarget FramebufferAttachment::cubeMapFace() const
 {
     ASSERT(mType == GL_TEXTURE);
 
     const auto &index = mTarget.textureIndex();
-    return index.type == GL_TEXTURE_CUBE_MAP ? index.target : GL_NONE;
+    return index.type == TextureType::CubeMap ? index.target : TextureTarget::InvalidEnum;
 }
 
 GLint FramebufferAttachment::mipLevel() const
 {
     ASSERT(type() == GL_TEXTURE);
     return mTarget.textureIndex().mipIndex;
 }
 
@@ -348,24 +348,34 @@ Error FramebufferAttachmentObject::getAt
     const Context *context,
     GLenum binding,
     const ImageIndex &imageIndex,
     rx::FramebufferAttachmentRenderTarget **rtOut) const
 {
     return getAttachmentImpl()->getAttachmentRenderTarget(context, binding, imageIndex, rtOut);
 }
 
+void FramebufferAttachmentObject::onStorageChange(const gl::Context *context) const
+{
+    return getAttachmentImpl()->onStateChange(context, angle::SubjectMessage::STORAGE_CHANGED);
+}
+
+angle::Subject *FramebufferAttachmentObject::getSubject() const
+{
+    return getAttachmentImpl();
+}
+
 Error FramebufferAttachmentObject::initializeContents(const Context *context,
                                                       const ImageIndex &imageIndex)
 {
     ASSERT(context->isRobustResourceInitEnabled());
 
     // Because gl::Texture cannot support tracking individual layer dirtiness, we only handle
     // initializing entire mip levels for 2D array textures.
-    if (imageIndex.type == GL_TEXTURE_2D_ARRAY && imageIndex.hasLayer())
+    if (imageIndex.type == TextureType::_2DArray && imageIndex.hasLayer())
     {
         ImageIndex fullMipIndex = imageIndex;
         fullMipIndex.layerIndex = ImageIndex::ENTIRE_LEVEL;
         return getAttachmentImpl()->initializeContents(context, fullMipIndex);
     }
     else
     {
         return getAttachmentImpl()->initializeContents(context, imageIndex);
--- a/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.h
+++ b/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.h
@@ -10,17 +10,16 @@
 #ifndef LIBANGLE_FRAMEBUFFERATTACHMENT_H_
 #define LIBANGLE_FRAMEBUFFERATTACHMENT_H_
 
 #include "angle_gl.h"
 #include "common/angleutils.h"
 #include "libANGLE/angletypes.h"
 #include "libANGLE/Error.h"
 #include "libANGLE/ImageIndex.h"
-#include "libANGLE/signal_utils.h"
 
 namespace egl
 {
 class Surface;
 }
 
 namespace rx
 {
@@ -31,16 +30,21 @@ class FramebufferAttachmentRenderTarget 
   public:
     FramebufferAttachmentRenderTarget() {}
     virtual ~FramebufferAttachmentRenderTarget() {}
 };
 
 class FramebufferAttachmentObjectImpl;
 }
 
+namespace angle
+{
+class Subject;
+}  // namespace angle
+
 namespace gl
 {
 class FramebufferAttachmentObject;
 struct Format;
 class Renderbuffer;
 class Texture;
 
 enum class InitState
@@ -95,17 +99,17 @@ class FramebufferAttachment final
     bool isTextureWithId(GLuint textureId) const { return mType == GL_TEXTURE && id() == textureId; }
     bool isRenderbufferWithId(GLuint renderbufferId) const { return mType == GL_RENDERBUFFER && id() == renderbufferId; }
 
     GLenum getBinding() const { return mTarget.binding(); }
     GLuint id() const;
 
     // These methods are only legal to call on Texture attachments
     const ImageIndex &getTextureImageIndex() const;
-    GLenum cubeMapFace() const;
+    TextureTarget cubeMapFace() const;
     GLint mipLevel() const;
     GLint layer() const;
     GLsizei getNumViews() const;
     GLenum getMultiviewLayout() const;
     GLint getBaseViewIndex() const;
     const std::vector<Offset> &getMultiviewViewportOffsets() const;
 
     // The size of the underlying resource the attachment points to. The 'depth' value will
@@ -175,17 +179,17 @@ class FramebufferAttachment final
     FramebufferAttachmentObject *mResource;
     GLsizei mNumViews;
     GLenum mMultiviewLayout;
     GLint mBaseViewIndex;
     std::vector<Offset> mViewportOffsets;
 };
 
 // A base class for objects that FBO Attachments may point to.
-class FramebufferAttachmentObject : public angle::Subject
+class FramebufferAttachmentObject
 {
   public:
     FramebufferAttachmentObject();
     virtual ~FramebufferAttachmentObject();
 
     virtual Extents getAttachmentSize(const ImageIndex &imageIndex) const = 0;
     virtual const Format &getAttachmentFormat(GLenum binding,
                                               const ImageIndex &imageIndex) const = 0;
@@ -201,16 +205,19 @@ class FramebufferAttachmentObject : publ
 
     Error getAttachmentRenderTarget(const Context *context,
                                     GLenum binding,
                                     const ImageIndex &imageIndex,
                                     rx::FramebufferAttachmentRenderTarget **rtOut) const;
 
     Error initializeContents(const Context *context, const ImageIndex &imageIndex);
 
+    void onStorageChange(const gl::Context *context) const;
+    angle::Subject *getSubject() const;
+
   protected:
     virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0;
 };
 
 inline Extents FramebufferAttachment::getSize() const
 {
     ASSERT(mResource);
     return mResource->getAttachmentSize(mTarget.textureIndex());
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/GLES1State.cpp
@@ -0,0 +1,271 @@
+//
+// 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.
+//
+
+// GLES1State.cpp: Implements the GLES1State class, tracking state
+// for GLES1 contexts.
+
+#include "libANGLE/GLES1State.h"
+
+#include "libANGLE/Context.h"
+
+namespace gl
+{
+
+TextureCoordF::TextureCoordF() = default;
+
+TextureCoordF::TextureCoordF(float _s, float _t, float _r, float _q) : s(_s), t(_t), r(_r), q(_q)
+{
+}
+
+bool TextureCoordF::operator==(const TextureCoordF &other) const
+{
+    return s == other.s && t == other.t && r == other.r && q == other.q;
+}
+
+GLES1State::GLES1State()
+    : mGLState(nullptr),
+      mVertexArrayEnabled(false),
+      mNormalArrayEnabled(false),
+      mColorArrayEnabled(false),
+      mPointSizeArrayEnabled(false),
+      mLineSmoothEnabled(false),
+      mPointSmoothEnabled(false),
+      mPointSpriteEnabled(false),
+      mAlphaTestEnabled(false),
+      mLogicOpEnabled(false),
+      mLightingEnabled(false),
+      mFogEnabled(false),
+      mRescaleNormalEnabled(false),
+      mNormalizeEnabled(false),
+      mColorMaterialEnabled(false),
+      mReflectionMapEnabled(false),
+      mCurrentColor({0.0f, 0.0f, 0.0f, 0.0f}),
+      mCurrentNormal({0.0f, 0.0f, 0.0f}),
+      mClientActiveTexture(0),
+      mMatrixMode(MatrixType::Modelview),
+      mShadeModel(ShadingModel::Smooth),
+      mAlphaTestFunc(AlphaTestFunc::AlwaysPass),
+      mAlphaTestRef(0.0f),
+      mLogicOp(LogicalOperation::Copy),
+      mLineSmoothHint(HintSetting::DontCare),
+      mPointSmoothHint(HintSetting::DontCare),
+      mPerspectiveCorrectionHint(HintSetting::DontCare),
+      mFogHint(HintSetting::DontCare)
+{
+}
+
+GLES1State::~GLES1State() = default;
+
+// Taken from the GLES 1.x spec which specifies all initial state values.
+void GLES1State::initialize(const Context *context, const State *state)
+{
+    mGLState = state;
+
+    const Caps &caps = context->getCaps();
+
+    mTexUnitEnables.resize(caps.maxMultitextureUnits);
+    for (auto &enables : mTexUnitEnables)
+    {
+        enables.enable2D      = false;
+        enables.enableCubeMap = false;
+    }
+
+    mVertexArrayEnabled    = false;
+    mNormalArrayEnabled    = false;
+    mColorArrayEnabled     = false;
+    mPointSizeArrayEnabled = false;
+    mTexCoordArrayEnabled.resize(caps.maxMultitextureUnits, false);
+
+    mLineSmoothEnabled    = false;
+    mPointSmoothEnabled   = false;
+    mPointSpriteEnabled   = false;
+    mLogicOpEnabled       = false;
+    mAlphaTestEnabled     = false;
+    mLightingEnabled      = false;
+    mFogEnabled           = false;
+    mRescaleNormalEnabled = false;
+    mNormalizeEnabled     = false;
+    mColorMaterialEnabled = false;
+    mReflectionMapEnabled = false;
+
+    mMatrixMode = MatrixType::Modelview;
+
+    mCurrentColor  = {1.0f, 1.0f, 1.0f, 1.0f};
+    mCurrentNormal = {0.0f, 0.0f, 1.0f};
+    mCurrentTextureCoords.resize(caps.maxMultitextureUnits);
+    mClientActiveTexture = 0;
+
+    mTextureEnvironments.resize(caps.maxMultitextureUnits);
+
+    mModelviewMatrices.push_back(angle::Mat4());
+    mProjectionMatrices.push_back(angle::Mat4());
+    mTextureMatrices.resize(caps.maxMultitextureUnits);
+    for (auto &stack : mTextureMatrices)
+    {
+        stack.push_back(angle::Mat4());
+    }
+
+    mMaterial.ambient  = {0.2f, 0.2f, 0.2f, 1.0f};
+    mMaterial.diffuse  = {0.8f, 0.8f, 0.8f, 1.0f};
+    mMaterial.specular = {0.0f, 0.0f, 0.0f, 1.0f};
+    mMaterial.emissive = {0.0f, 0.0f, 0.0f, 1.0f};
+
+    mMaterial.specularExponent = 0.0f;
+
+    mLightModel.color    = {0.2f, 0.2f, 0.2f, 1.0f};
+    mLightModel.twoSided = false;
+
+    mLights.resize(caps.maxLights);
+
+    // GL_LIGHT0 is special and has default state that avoids all-black renderings.
+    mLights[0].diffuse  = {1.0f, 1.0f, 1.0f, 1.0f};
+    mLights[0].specular = {1.0f, 1.0f, 1.0f, 1.0f};
+
+    mFog.mode    = FogMode::Exp;
+    mFog.density = 1.0f;
+    mFog.start   = 0.0f;
+    mFog.end     = 1.0f;
+
+    mFog.color = {0.0f, 0.0f, 0.0f, 0.0f};
+
+    mShadeModel = ShadingModel::Smooth;
+
+    mAlphaTestFunc = AlphaTestFunc::AlwaysPass;
+    mAlphaTestRef  = 0.0f;
+
+    mLogicOp = LogicalOperation::Copy;
+
+    mClipPlaneEnabled.resize(caps.maxClipPlanes, false);
+
+    mClipPlanes.resize(caps.maxClipPlanes, angle::Vector4(0.0f, 0.0f, 0.0f, 0.0f));
+
+    mPointParameters.pointSizeMin                = 0.1f;
+    mPointParameters.pointSizeMax                = 100.0f;
+    mPointParameters.pointFadeThresholdSize      = 0.1f;
+    mPointParameters.pointDistanceAttenuation[0] = 1.0f;
+    mPointParameters.pointDistanceAttenuation[1] = 0.0f;
+    mPointParameters.pointDistanceAttenuation[2] = 0.0f;
+
+    mPointParameters.pointSize = 1.0f;
+
+    mLineSmoothHint            = HintSetting::DontCare;
+    mPointSmoothHint           = HintSetting::DontCare;
+    mPerspectiveCorrectionHint = HintSetting::DontCare;
+    mFogHint                   = HintSetting::DontCare;
+}
+
+void GLES1State::setAlphaFunc(AlphaTestFunc func, GLfloat ref)
+{
+    mAlphaTestFunc = func;
+    mAlphaTestRef  = ref;
+}
+
+void GLES1State::setClientTextureUnit(unsigned int unit)
+{
+    mClientActiveTexture = unit;
+}
+
+unsigned int GLES1State::getClientTextureUnit() const
+{
+    return mClientActiveTexture;
+}
+
+void GLES1State::setCurrentColor(const ColorF &color)
+{
+    mCurrentColor = color;
+}
+
+const ColorF &GLES1State::getCurrentColor() const
+{
+    return mCurrentColor;
+}
+
+void GLES1State::setCurrentNormal(const angle::Vector3 &normal)
+{
+    mCurrentNormal = normal;
+}
+
+const angle::Vector3 &GLES1State::getCurrentNormal() const
+{
+    return mCurrentNormal;
+}
+
+void GLES1State::setCurrentTextureCoords(unsigned int unit, const TextureCoordF &coords)
+{
+    mCurrentTextureCoords[unit] = coords;
+}
+
+const TextureCoordF &GLES1State::getCurrentTextureCoords(unsigned int unit) const
+{
+    return mCurrentTextureCoords[unit];
+}
+
+void GLES1State::setMatrixMode(MatrixType mode)
+{
+    mMatrixMode = mode;
+}
+
+MatrixType GLES1State::getMatrixMode() const
+{
+    return mMatrixMode;
+}
+
+void GLES1State::pushMatrix()
+{
+    auto &stack = currentMatrixStack();
+    stack.push_back(stack.back());
+}
+
+void GLES1State::popMatrix()
+{
+    auto &stack = currentMatrixStack();
+    stack.pop_back();
+}
+
+GLES1State::MatrixStack &GLES1State::currentMatrixStack()
+{
+    switch (mMatrixMode)
+    {
+        case MatrixType::Modelview:
+            return mModelviewMatrices;
+        case MatrixType::Projection:
+            return mProjectionMatrices;
+        case MatrixType::Texture:
+            return mTextureMatrices[mGLState->getActiveSampler()];
+        default:
+            UNREACHABLE();
+            return mModelviewMatrices;
+    }
+}
+
+const GLES1State::MatrixStack &GLES1State::currentMatrixStack() const
+{
+    switch (mMatrixMode)
+    {
+        case MatrixType::Modelview:
+            return mModelviewMatrices;
+        case MatrixType::Projection:
+            return mProjectionMatrices;
+        case MatrixType::Texture:
+            return mTextureMatrices[mGLState->getActiveSampler()];
+        default:
+            UNREACHABLE();
+            return mModelviewMatrices;
+    }
+}
+
+void GLES1State::loadMatrix(const angle::Mat4 &m)
+{
+    currentMatrixStack().back() = m;
+}
+
+void GLES1State::multMatrix(const angle::Mat4 &m)
+{
+    angle::Mat4 currentMatrix             = currentMatrixStack().back();
+    currentMatrixStack().back() = currentMatrix.product(m);
+}
+
+}  // namespace gl
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/GLES1State.h
@@ -0,0 +1,239 @@
+//
+// 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.
+//
+
+// GLES1State.h: Defines the GLES1State class holding the state of
+// a GLES1 context.
+
+#ifndef LIBANGLE_GLES1STATE_H_
+#define LIBANGLE_GLES1STATE_H_
+
+#include <unordered_set>
+
+#include "common/FixedVector.h"
+#include "common/angleutils.h"
+#include "common/matrix_utils.h"
+#include "common/vector_utils.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/angletypes.h"
+
+namespace gl
+{
+
+// State types specific to GLES1 contexts, from the OpenGL ES 1.1 spec "State Tables" section
+struct TextureCoordF
+{
+    TextureCoordF();
+    TextureCoordF(float _s, float _t, float _r, float _q);
+    bool operator==(const TextureCoordF &other) const;
+
+    GLfloat s = 0.0f;
+    GLfloat t = 0.0f;
+    GLfloat r = 0.0f;
+    GLfloat q = 0.0f;
+};
+
+struct MaterialParameters
+{
+    ColorF ambient;
+    ColorF diffuse;
+    ColorF specular;
+    ColorF emissive;
+    GLfloat specularExponent;
+};
+
+struct LightModelParameters
+{
+    ColorF color;
+    bool twoSided;
+};
+
+struct LightParameters
+{
+    bool enabled                 = false;
+    ColorF ambient               = {0.0f, 0.0f, 0.0f, 1.0f};
+    ColorF diffuse               = {0.0f, 0.0f, 0.0f, 1.0f};
+    ColorF specular              = {0.0f, 0.0f, 0.0f, 1.0f};
+    angle::Vector4 position      = {0.0f, 0.0f, 1.0f, 0.0f};
+    angle::Vector3 direction     = {0.0f, 0.0f, -1.0f};
+    GLfloat spotlightExponent    = 0.0f;
+    GLfloat spotlightCutoffAngle = 180.0f;
+    GLfloat attenuationConst     = 1.0f;
+    GLfloat attenuationLinear    = 0.0f;
+    GLfloat attenuationQuadratic = 0.0f;
+};
+
+struct FogParameters
+{
+    FogMode mode;
+    GLfloat density;
+    GLfloat start;
+    GLfloat end;
+    ColorF color;
+};
+
+struct TextureEnvironmentParameters
+{
+    TextureEnvMode envMode      = TextureEnvMode::Modulate;
+    TextureCombine combineRgb   = TextureCombine::Modulate;
+    TextureCombine combineAlpha = TextureCombine::Modulate;
+
+    TextureSrc src0rgb   = TextureSrc::Texture;
+    TextureSrc src0alpha = TextureSrc::Texture;
+
+    TextureSrc src1rgb   = TextureSrc::Previous;
+    TextureSrc src1alpha = TextureSrc::Previous;
+
+    TextureSrc src2rgb   = TextureSrc::Constant;
+    TextureSrc src2alpha = TextureSrc::Constant;
+
+    TextureOp op0rgb   = TextureOp::SrcColor;
+    TextureOp op0alpha = TextureOp::SrcAlpha;
+
+    TextureOp op1rgb   = TextureOp::SrcColor;
+    TextureOp op1alpha = TextureOp::SrcAlpha;
+
+    TextureOp op2rgb   = TextureOp::SrcAlpha;
+    TextureOp op2alpha = TextureOp::SrcAlpha;
+
+    ColorF envColor    = {0.0f, 0.0f, 0.0f, 0.0f};
+    GLfloat rgbScale   = 1.0f;
+    GLfloat alphaScale = 1.0f;
+
+    bool pointSpriteCoordReplace = false;
+};
+
+struct PointParameters
+{
+    GLfloat pointSizeMin;
+    GLfloat pointSizeMax;
+    GLfloat pointFadeThresholdSize;
+    angle::Vector3 pointDistanceAttenuation;
+    GLfloat pointSize;
+};
+
+class Context;
+class State;
+class GLES1State final : angle::NonCopyable
+{
+  public:
+    GLES1State();
+    ~GLES1State();
+
+    void initialize(const Context *context, const State *state);
+
+    void setAlphaFunc(AlphaTestFunc func, GLfloat ref);
+    void setClientTextureUnit(unsigned int unit);
+    unsigned int getClientTextureUnit() const;
+
+    void setCurrentColor(const ColorF &color);
+    const ColorF &getCurrentColor() const;
+
+    void setCurrentNormal(const angle::Vector3 &normal);
+    const angle::Vector3 &getCurrentNormal() const;
+
+    void setCurrentTextureCoords(unsigned int unit, const TextureCoordF &coords);
+    const TextureCoordF &getCurrentTextureCoords(unsigned int unit) const;
+
+    void setMatrixMode(MatrixType mode);
+    MatrixType getMatrixMode() const;
+
+    void pushMatrix();
+    void popMatrix();
+
+    using MatrixStack = angle::FixedVector<angle::Mat4, Caps::GlobalMatrixStackDepth>;
+    MatrixStack &currentMatrixStack();
+    const MatrixStack &currentMatrixStack() const;
+
+    void loadMatrix(const angle::Mat4 &m);
+    void multMatrix(const angle::Mat4 &m);
+
+  private:
+    friend class State;
+
+    // Back pointer for reading from State.
+    const State *mGLState;
+
+    // All initial state values come from the
+    // OpenGL ES 1.1 spec.
+    struct TextureEnables
+    {
+        bool enable2D      = false;
+        bool enableCubeMap = false;
+    };
+    std::vector<TextureEnables> mTexUnitEnables;
+
+    // Table 6.4, 6.5 (IsEnabled)
+    bool mVertexArrayEnabled;
+    bool mNormalArrayEnabled;
+    bool mColorArrayEnabled;
+    bool mPointSizeArrayEnabled;
+    std::vector<bool> mTexCoordArrayEnabled;
+
+    // Table 6.7-6.16 (IsEnabled)
+    std::vector<bool> mClipPlaneEnabled;
+    bool mLineSmoothEnabled;
+    bool mPointSmoothEnabled;
+    bool mPointSpriteEnabled;
+    bool mAlphaTestEnabled;
+    bool mLogicOpEnabled;
+    bool mLightingEnabled;
+    bool mFogEnabled;
+    bool mRescaleNormalEnabled;
+    bool mNormalizeEnabled;
+    bool mColorMaterialEnabled;
+    bool mReflectionMapEnabled;
+
+    // Table 6.3
+    ColorF mCurrentColor;
+    angle::Vector3 mCurrentNormal;
+    // Invariant: mCurrentTextureCoords size is == GL_MAX_TEXTURE_UNITS.
+    std::vector<TextureCoordF> mCurrentTextureCoords;
+
+    // Table 6.4
+    unsigned int mClientActiveTexture;
+
+    // Table 6.7
+    MatrixType mMatrixMode;
+    MatrixStack mProjectionMatrices;
+    MatrixStack mModelviewMatrices;
+    std::vector<MatrixStack> mTextureMatrices;
+
+    // Table 6.15
+    using TextureEnvironments = std::vector<TextureEnvironmentParameters>;
+    TextureEnvironments mTextureEnvironments;
+
+    // Table 6.9, 2.8
+    MaterialParameters mMaterial;
+    LightModelParameters mLightModel;
+
+    // Table 6.10
+    std::vector<LightParameters> mLights;
+
+    // Table 6.8
+    FogParameters mFog;
+    ShadingModel mShadeModel;
+
+    // Table 6.11
+    PointParameters mPointParameters;
+
+    // Table 6.16
+    AlphaTestFunc mAlphaTestFunc;
+    GLfloat mAlphaTestRef;
+    LogicalOperation mLogicOp;
+
+    // Table 6.7
+    std::vector<angle::Vector4> mClipPlanes;
+
+    // Table 6.19
+    HintSetting mLineSmoothHint;
+    HintSetting mPointSmoothHint;
+    HintSetting mPerspectiveCorrectionHint;
+    HintSetting mFogHint;
+};
+
+}  // namespace gl
+
+#endif  // LIBANGLE_GLES1STATE_H_
--- a/gfx/angle/checkout/src/libANGLE/HandleAllocator.cpp
+++ b/gfx/angle/checkout/src/libANGLE/HandleAllocator.cpp
@@ -25,17 +25,18 @@ struct HandleAllocator::HandleRangeCompa
     }
 };
 
 HandleAllocator::HandleAllocator() : mBaseValue(1), mNextValue(1), mLoggingEnabled(false)
 {
     mUnallocatedList.push_back(HandleRange(1, std::numeric_limits<GLuint>::max()));
 }
 
-HandleAllocator::HandleAllocator(GLuint maximumHandleValue) : mBaseValue(1), mNextValue(1)
+HandleAllocator::HandleAllocator(GLuint maximumHandleValue)
+    : mBaseValue(1), mNextValue(1), mLoggingEnabled(false)
 {
     mUnallocatedList.push_back(HandleRange(1, maximumHandleValue));
 }
 
 HandleAllocator::~HandleAllocator()
 {
 }
 
--- a/gfx/angle/checkout/src/libANGLE/Image.cpp
+++ b/gfx/angle/checkout/src/libANGLE/Image.cpp
@@ -24,21 +24,21 @@ namespace
 {
 gl::ImageIndex GetImageIndex(EGLenum eglTarget, const egl::AttributeMap &attribs)
 {
     if (eglTarget == EGL_GL_RENDERBUFFER)
     {
         return gl::ImageIndex::MakeInvalid();
     }
 
-    GLenum target = egl_gl::EGLImageTargetToGLTextureTarget(eglTarget);
+    gl::TextureTarget target = egl_gl::EGLImageTargetToTextureTarget(eglTarget);
     GLint mip     = static_cast<GLint>(attribs.get(EGL_GL_TEXTURE_LEVEL_KHR, 0));
     GLint layer   = static_cast<GLint>(attribs.get(EGL_GL_TEXTURE_ZOFFSET_KHR, 0));
 
-    if (target == GL_TEXTURE_3D)
+    if (target == gl::TextureTarget::_3D)
     {
         return gl::ImageIndex::Make3D(mip, layer);
     }
     else
     {
         ASSERT(layer == 0);
         return gl::ImageIndex::MakeGeneric(target, mip);
     }
--- a/gfx/angle/checkout/src/libANGLE/ImageIndex.cpp
+++ b/gfx/angle/checkout/src/libANGLE/ImageIndex.cpp
@@ -16,77 +16,77 @@
 namespace gl
 {
 
 ImageIndex::ImageIndex(const ImageIndex &other) = default;
 ImageIndex &ImageIndex::operator=(const ImageIndex &other) = default;
 
 bool ImageIndex::is3D() const
 {
-    return type == GL_TEXTURE_3D || type == GL_TEXTURE_2D_ARRAY;
+    return type == TextureType::_3D || type == TextureType::_2DArray;
 }
 
 GLint ImageIndex::cubeMapFaceIndex() const
 {
-    ASSERT(type == GL_TEXTURE_CUBE_MAP);
-    ASSERT(target >= gl::FirstCubeMapTextureTarget && target <= gl::LastCubeMapTextureTarget);
-    return target - gl::FirstCubeMapTextureTarget;
+    ASSERT(type == TextureType::CubeMap);
+    ASSERT(TextureTargetToType(target) == TextureType::CubeMap);
+    return static_cast<GLint>(CubeMapTextureTargetToFaceIndex(target));
 }
 
 bool ImageIndex::valid() const
 {
-    return type != GL_NONE;
+    return type != TextureType::InvalidEnum;
 }
 
 ImageIndex ImageIndex::Make2D(GLint mipIndex)
 {
-    return ImageIndex(GL_TEXTURE_2D, GL_TEXTURE_2D, mipIndex, ENTIRE_LEVEL, 1);
+    return ImageIndex(TextureType::_2D, TextureTarget::_2D, mipIndex, ENTIRE_LEVEL, 1);
 }
 
 ImageIndex ImageIndex::MakeRectangle(GLint mipIndex)
 {
-    return ImageIndex(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_RECTANGLE_ANGLE, mipIndex,
-                      ENTIRE_LEVEL, 1);
+    return ImageIndex(TextureType::Rectangle, TextureTarget::Rectangle, mipIndex, ENTIRE_LEVEL, 1);
 }
 
-ImageIndex ImageIndex::MakeCube(GLenum target, GLint mipIndex)
+ImageIndex ImageIndex::MakeCube(TextureTarget target, GLint mipIndex)
 {
-    ASSERT(gl::IsCubeMapTextureTarget(target));
-    return ImageIndex(GL_TEXTURE_CUBE_MAP, target, mipIndex, ENTIRE_LEVEL, 1);
+    ASSERT(TextureTargetToType(target) == TextureType::CubeMap);
+    return ImageIndex(TextureType::CubeMap, target, mipIndex, ENTIRE_LEVEL, 1);
 }
 
 ImageIndex ImageIndex::Make2DArray(GLint mipIndex, GLint layerIndex)
 {
-    return ImageIndex(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_2D_ARRAY, mipIndex, layerIndex, 1);
+    return ImageIndex(TextureType::_2DArray, TextureTarget::_2DArray, mipIndex, layerIndex, 1);
 }
 
 ImageIndex ImageIndex::Make2DArrayRange(GLint mipIndex, GLint layerIndex, GLint numLayers)
 {
-    return ImageIndex(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_2D_ARRAY, mipIndex, layerIndex, numLayers);
+    return ImageIndex(TextureType::_2DArray, TextureTarget::_2DArray, mipIndex, layerIndex,
+                      numLayers);
 }
 
 ImageIndex ImageIndex::Make3D(GLint mipIndex, GLint layerIndex)
 {
-    return ImageIndex(GL_TEXTURE_3D, GL_TEXTURE_3D, mipIndex, layerIndex, 1);
+    return ImageIndex(TextureType::_3D, TextureTarget::_3D, mipIndex, layerIndex, 1);
 }
 
-ImageIndex ImageIndex::MakeGeneric(GLenum target, GLint mipIndex)
+ImageIndex ImageIndex::MakeGeneric(TextureTarget target, GLint mipIndex)
 {
-    GLenum textureType = IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target;
-    return ImageIndex(textureType, target, mipIndex, ENTIRE_LEVEL, 1);
+    return ImageIndex(TextureTargetToType(target), target, mipIndex, ENTIRE_LEVEL, 1);
 }
 
 ImageIndex ImageIndex::Make2DMultisample()
 {
-    return ImageIndex(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE, 0, ENTIRE_LEVEL, 1);
+    return ImageIndex(TextureType::_2DMultisample, TextureTarget::_2DMultisample, 0, ENTIRE_LEVEL,
+                      1);
 }
 
 ImageIndex ImageIndex::MakeInvalid()
 {
-    return ImageIndex(GL_NONE, GL_NONE, -1, -1, -1);
+    return ImageIndex(TextureType::InvalidEnum, TextureTarget::InvalidEnum, -1, -1, -1);
 }
 
 bool operator<(const ImageIndex &a, const ImageIndex &b)
 {
     return std::tie(a.type, a.target, a.mipIndex, a.layerIndex, a.numLayers) <
            std::tie(b.type, b.target, b.mipIndex, b.layerIndex, b.numLayers);
 }
 
@@ -96,90 +96,103 @@ bool operator==(const ImageIndex &a, con
            std::tie(b.type, b.target, b.mipIndex, b.layerIndex, b.numLayers);
 }
 
 bool operator!=(const ImageIndex &a, const ImageIndex &b)
 {
     return !(a == b);
 }
 
-ImageIndex::ImageIndex(GLenum typeIn,
-                       GLenum targetIn,
+ImageIndex::ImageIndex(TextureType typeIn,
+                       TextureTarget targetIn,
                        GLint mipIndexIn,
                        GLint layerIndexIn,
                        GLint numLayersIn)
     : type(typeIn),
       target(targetIn),
       mipIndex(mipIndexIn),
       layerIndex(layerIndexIn),
       numLayers(numLayersIn)
 {}
 
 ImageIndexIterator::ImageIndexIterator(const ImageIndexIterator &other) = default;
 
 ImageIndexIterator ImageIndexIterator::Make2D(GLint minMip, GLint maxMip)
 {
     return ImageIndexIterator(
-        GL_TEXTURE_2D, Range<GLenum>(GL_TEXTURE_2D, GL_TEXTURE_2D), Range<GLint>(minMip, maxMip),
+        TextureType::_2D, TextureTarget::_2D, TextureTarget::_2D, Range<GLint>(minMip, maxMip),
         Range<GLint>(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL), nullptr);
 }
 
 ImageIndexIterator ImageIndexIterator::MakeRectangle(GLint minMip, GLint maxMip)
 {
-    return ImageIndexIterator(GL_TEXTURE_RECTANGLE_ANGLE,
-                              Range<GLenum>(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_RECTANGLE_ANGLE),
-                              Range<GLint>(minMip, maxMip),
+    return ImageIndexIterator(TextureType::Rectangle, TextureTarget::Rectangle,
+                              TextureTarget::Rectangle, Range<GLint>(minMip, maxMip),
                               Range<GLint>(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL),
                               nullptr);
 }
 
 ImageIndexIterator ImageIndexIterator::MakeCube(GLint minMip, GLint maxMip)
 {
-    return ImageIndexIterator(
-        GL_TEXTURE_CUBE_MAP,
-        Range<GLenum>(gl::FirstCubeMapTextureTarget, gl::LastCubeMapTextureTarget),
-        Range<GLint>(minMip, maxMip),
-        Range<GLint>(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL), nullptr);
+    return ImageIndexIterator(TextureType::CubeMap, kCubeMapTextureTargetMin,
+                              kCubeMapTextureTargetMax, Range<GLint>(minMip, maxMip),
+                              Range<GLint>(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL),
+                              nullptr);
 }
 
 ImageIndexIterator ImageIndexIterator::Make3D(GLint minMip, GLint maxMip,
                                               GLint minLayer, GLint maxLayer)
 {
-    return ImageIndexIterator(GL_TEXTURE_3D, Range<GLenum>(GL_TEXTURE_3D, GL_TEXTURE_3D),
+    return ImageIndexIterator(TextureType::_3D, TextureTarget::_3D, TextureTarget::_3D,
                               Range<GLint>(minMip, maxMip), Range<GLint>(minLayer, maxLayer),
                               nullptr);
 }
 
 ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip, GLint maxMip,
                                                    const GLsizei *layerCounts)
 {
-    return ImageIndexIterator(
-        GL_TEXTURE_2D_ARRAY, Range<GLenum>(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_2D_ARRAY),
-        Range<GLint>(minMip, maxMip), Range<GLint>(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS),
-        layerCounts);
+    return ImageIndexIterator(TextureType::_2DArray, TextureTarget::_2DArray,
+                              TextureTarget::_2DArray, Range<GLint>(minMip, maxMip),
+                              Range<GLint>(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS),
+                              layerCounts);
 }
 
 ImageIndexIterator ImageIndexIterator::Make2DMultisample()
 {
-    return ImageIndexIterator(
-        GL_TEXTURE_2D_MULTISAMPLE,
-        Range<GLenum>(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE), Range<GLint>(0, 0),
-        Range<GLint>(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL), nullptr);
+    return ImageIndexIterator(TextureType::_2DMultisample, TextureTarget::_2DMultisample,
+                              TextureTarget::_2DMultisample, Range<GLint>(0, 0),
+                              Range<GLint>(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL),
+                              nullptr);
 }
 
-ImageIndexIterator::ImageIndexIterator(GLenum type,
-                                       const Range<GLenum> &targetRange,
+ImageIndexIterator ImageIndexIterator::MakeGeneric(TextureType type, GLint minMip, GLint maxMip)
+{
+    if (type == TextureType::CubeMap)
+    {
+        return MakeCube(minMip, maxMip);
+    }
+
+    TextureTarget target = NonCubeTextureTypeToTarget(type);
+    return ImageIndexIterator(type, target, target, Range<GLint>(minMip, maxMip),
+                              Range<GLint>(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL),
+                              nullptr);
+}
+
+ImageIndexIterator::ImageIndexIterator(TextureType type,
+                                       angle::EnumIterator<TextureTarget> targetLow,
+                                       angle::EnumIterator<TextureTarget> targetHigh,
                                        const Range<GLint> &mipRange,
                                        const Range<GLint> &layerRange,
                                        const GLsizei *layerCounts)
-    : mTargetRange(targetRange),
+    : mTargetLow(targetLow),
+      mTargetHigh(targetHigh),
       mMipRange(mipRange),
       mLayerRange(layerRange),
       mLayerCounts(layerCounts),
-      mCurrentIndex(type, targetRange.low(), mipRange.low(), layerRange.low(), 1)
+      mCurrentIndex(type, *targetLow, mipRange.low(), layerRange.low(), 1)
 {}
 
 GLint ImageIndexIterator::maxLayer() const
 {
     if (mLayerCounts)
     {
         ASSERT(mCurrentIndex.hasLayer());
         return (mCurrentIndex.mipIndex < mMipRange.high()) ? mLayerCounts[mCurrentIndex.mipIndex]
@@ -193,28 +206,30 @@ ImageIndex ImageIndexIterator::next()
     ASSERT(hasNext());
 
     // Make a copy of the current index to return
     ImageIndex previousIndex = mCurrentIndex;
 
     // Iterate layers in the inner loop for now. We can add switchable
     // layer or mip iteration if we need it.
 
-    if (mCurrentIndex.target < mTargetRange.high())
+    angle::EnumIterator<TextureTarget> currentTarget = mCurrentIndex.target;
+    if (currentTarget != mTargetHigh)
     {
-        mCurrentIndex.target++;
+        ++currentTarget;
+        mCurrentIndex.target = *currentTarget;
     }
     else if (mCurrentIndex.hasLayer() && mCurrentIndex.layerIndex < maxLayer() - 1)
     {
-        mCurrentIndex.target = mTargetRange.low();
+        mCurrentIndex.target = *mTargetLow;
         mCurrentIndex.layerIndex++;
     }
     else if (mCurrentIndex.mipIndex < mMipRange.high() - 1)
     {
-        mCurrentIndex.target     = mTargetRange.low();
+        mCurrentIndex.target     = *mTargetLow;
         mCurrentIndex.layerIndex = mLayerRange.low();
         mCurrentIndex.mipIndex++;
     }
     else
     {
         mCurrentIndex = ImageIndex::MakeInvalid();
     }
 
--- a/gfx/angle/checkout/src/libANGLE/ImageIndex.h
+++ b/gfx/angle/checkout/src/libANGLE/ImageIndex.h
@@ -5,95 +5,106 @@
 //
 
 // ImageIndex.h: A helper struct for indexing into an Image array
 
 #ifndef LIBANGLE_IMAGE_INDEX_H_
 #define LIBANGLE_IMAGE_INDEX_H_
 
 #include "common/mathutil.h"
+#include "libANGLE/PackedGLEnums.h"
 
 #include "angle_gl.h"
 
 namespace gl
 {
 
 class ImageIndexIterator;
 
 struct ImageIndex
 {
-    GLenum type;
-    GLenum target;
+    TextureType type;
+    TextureTarget target;
 
     GLint mipIndex;
 
     GLint layerIndex;
     GLint numLayers;
 
     ImageIndex(const ImageIndex &other);
     ImageIndex &operator=(const ImageIndex &other);
 
     bool hasLayer() const { return layerIndex != ENTIRE_LEVEL; }
     bool is3D() const;
     GLint cubeMapFaceIndex() const;
     bool valid() const;
 
     static ImageIndex Make2D(GLint mipIndex);
     static ImageIndex MakeRectangle(GLint mipIndex);
-    static ImageIndex MakeCube(GLenum target, GLint mipIndex);
+    static ImageIndex MakeCube(TextureTarget target, GLint mipIndex);
     static ImageIndex Make2DArray(GLint mipIndex, GLint layerIndex);
     static ImageIndex Make2DArrayRange(GLint mipIndex, GLint layerIndex, GLint numLayers);
     static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = ENTIRE_LEVEL);
-    static ImageIndex MakeGeneric(GLenum target, GLint mipIndex);
+    static ImageIndex MakeGeneric(TextureTarget target, GLint mipIndex);
     static ImageIndex Make2DMultisample();
 
     static ImageIndex MakeInvalid();
 
     static const GLint ENTIRE_LEVEL = static_cast<GLint>(-1);
 
   private:
     friend class ImageIndexIterator;
 
-    ImageIndex(GLenum typeIn,
-               GLenum targetIn,
+    ImageIndex(TextureType typeIn,
+               TextureTarget targetIn,
                GLint mipIndexIn,
                GLint layerIndexIn,
                GLint numLayersIn);
 };
 
 bool operator<(const ImageIndex &a, const ImageIndex &b);
 bool operator==(const ImageIndex &a, const ImageIndex &b);
 bool operator!=(const ImageIndex &a, const ImageIndex &b);
 
+// To be used like this:
+//
+// ImageIndexIterator it = ...;
+// while (it.hasNext())
+// {
+//     ImageIndex current = it.next();
+// }
 class ImageIndexIterator
 {
   public:
     ImageIndexIterator(const ImageIndexIterator &other);
 
     static ImageIndexIterator Make2D(GLint minMip, GLint maxMip);
     static ImageIndexIterator MakeRectangle(GLint minMip, GLint maxMip);
     static ImageIndexIterator MakeCube(GLint minMip, GLint maxMip);
     static ImageIndexIterator Make3D(GLint minMip, GLint maxMip, GLint minLayer, GLint maxLayer);
     static ImageIndexIterator Make2DArray(GLint minMip, GLint maxMip, const GLsizei *layerCounts);
     static ImageIndexIterator Make2DMultisample();
+    static ImageIndexIterator MakeGeneric(TextureType type, GLint minMip, GLint maxMip);
 
     ImageIndex next();
     ImageIndex current() const;
     bool hasNext() const;
 
   private:
-    ImageIndexIterator(GLenum type,
-                       const Range<GLenum> &targetRange,
+    ImageIndexIterator(TextureType type,
+                       angle::EnumIterator<TextureTarget> targetLow,
+                       angle::EnumIterator<TextureTarget> targetHigh,
                        const Range<GLint> &mipRange,
                        const Range<GLint> &layerRange,
                        const GLsizei *layerCounts);
 
     GLint maxLayer() const;
 
-    const Range<GLenum> mTargetRange;
+    const angle::EnumIterator<TextureTarget> mTargetLow;
+    const angle::EnumIterator<TextureTarget> mTargetHigh;
     const Range<GLint> mMipRange;
     const Range<GLint> mLayerRange;
     const GLsizei *const mLayerCounts;
 
     ImageIndex mCurrentIndex;
 };
 
 }
--- a/gfx/angle/checkout/src/libANGLE/MemoryProgramCache.cpp
+++ b/gfx/angle/checkout/src/libANGLE/MemoryProgramCache.cpp
@@ -39,54 +39,59 @@ constexpr unsigned int kWarningLimit = 3
 void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var)
 {
     stream->writeInt(var.type);
     stream->writeInt(var.precision);
     stream->writeString(var.name);
     stream->writeString(var.mappedName);
     stream->writeIntVector(var.arraySizes);
     stream->writeInt(var.staticUse);
+    stream->writeInt(var.active);
     stream->writeString(var.structName);
     ASSERT(var.fields.empty());
 }
 
 void LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var)
 {
     var->type       = stream->readInt<GLenum>();
     var->precision  = stream->readInt<GLenum>();
     var->name       = stream->readString();
     var->mappedName = stream->readString();
     stream->readIntVector<unsigned int>(&var->arraySizes);
     var->staticUse  = stream->readBool();
+    var->active     = stream->readBool();
     var->structName = stream->readString();
 }
 
 void WriteShaderVariableBuffer(BinaryOutputStream *stream, const ShaderVariableBuffer &var)
 {
     stream->writeInt(var.binding);
     stream->writeInt(var.dataSize);
 
-    stream->writeInt(var.vertexStaticUse);
-    stream->writeInt(var.fragmentStaticUse);
-    stream->writeInt(var.computeStaticUse);
+    for (ShaderType shaderType : AllShaderTypes())
+    {
+        stream->writeInt(var.isActive(shaderType));
+    }
 
     stream->writeInt(var.memberIndexes.size());
     for (unsigned int memberCounterIndex : var.memberIndexes)
     {
         stream->writeInt(memberCounterIndex);
     }
 }
 
 void LoadShaderVariableBuffer(BinaryInputStream *stream, ShaderVariableBuffer *var)
 {
     var->binding           = stream->readInt<int>();
     var->dataSize          = stream->readInt<unsigned int>();
-    var->vertexStaticUse   = stream->readBool();
-    var->fragmentStaticUse = stream->readBool();
-    var->computeStaticUse  = stream->readBool();
+
+    for (ShaderType shaderType : AllShaderTypes())
+    {
+        var->setActive(shaderType, stream->readBool());
+    }
 
     unsigned int numMembers = stream->readInt<unsigned int>();
     for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++)
     {
         var->memberIndexes.push_back(stream->readInt<unsigned int>());
     }
 }
 
@@ -96,35 +101,39 @@ void WriteBufferVariable(BinaryOutputStr
 
     stream->writeInt(var.bufferIndex);
     stream->writeInt(var.blockInfo.offset);
     stream->writeInt(var.blockInfo.arrayStride);
     stream->writeInt(var.blockInfo.matrixStride);
     stream->writeInt(var.blockInfo.isRowMajorMatrix);
     stream->writeInt(var.blockInfo.topLevelArrayStride);
     stream->writeInt(var.topLevelArraySize);
-    stream->writeInt(var.vertexStaticUse);
-    stream->writeInt(var.fragmentStaticUse);
-    stream->writeInt(var.computeStaticUse);
+
+    for (ShaderType shaderType : AllShaderTypes())
+    {
+        stream->writeInt(var.isActive(shaderType));
+    }
 }
 
 void LoadBufferVariable(BinaryInputStream *stream, BufferVariable *var)
 {
     LoadShaderVar(stream, var);
 
     var->bufferIndex                   = stream->readInt<int>();
     var->blockInfo.offset              = stream->readInt<int>();
     var->blockInfo.arrayStride         = stream->readInt<int>();
     var->blockInfo.matrixStride        = stream->readInt<int>();
     var->blockInfo.isRowMajorMatrix    = stream->readBool();
     var->blockInfo.topLevelArrayStride = stream->readInt<int>();
     var->topLevelArraySize             = stream->readInt<int>();
-    var->vertexStaticUse               = stream->readBool();
-    var->fragmentStaticUse             = stream->readBool();
-    var->computeStaticUse              = stream->readBool();
+
+    for (ShaderType shaderType : AllShaderTypes())
+    {
+        var->setActive(shaderType, stream->readBool());
+    }
 }
 
 void WriteInterfaceBlock(BinaryOutputStream *stream, const InterfaceBlock &block)
 {
     stream->writeString(block.name);
     stream->writeString(block.mappedName);
     stream->writeInt(block.isArray);
     stream->writeInt(block.arrayElement);
@@ -235,21 +244,21 @@ LinkResult MemoryProgramCache::Deseriali
     state->mGeometryShaderInvocations         = stream.readInt<int>();
     state->mGeometryShaderMaxVertices         = stream.readInt<int>();
 
     state->mNumViews = stream.readInt<int>();
 
     static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8,
                   "All bits of mAttributesTypeMask types and mask fit into 32 bits each");
     state->mAttributesTypeMask.from_ulong(stream.readInt<uint32_t>());
-    state->mAttributesMask = stream.readInt<uint32_t>();
+    state->mAttributesMask = stream.readInt<gl::AttributesMask>();
 
     static_assert(MAX_VERTEX_ATTRIBS <= sizeof(unsigned long) * 8,
                   "Too many vertex attribs for mask");
-    state->mActiveAttribLocationsMask = stream.readInt<unsigned long>();
+    state->mActiveAttribLocationsMask = stream.readInt<gl::AttributesMask>();
 
     unsigned int attribCount = stream.readInt<unsigned int>();
     ASSERT(state->mAttributes.empty());
     for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex)
     {
         sh::Attribute attrib;
         LoadShaderVar(&stream, &attrib);
         attrib.location = stream.readInt<int>();
@@ -381,25 +390,25 @@ LinkResult MemoryProgramCache::Deseriali
     {
         state->mOutputVariableTypes.push_back(stream.readInt<GLenum>());
     }
 
     static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS * 2 <= 8 * sizeof(uint32_t),
                   "All bits of mDrawBufferTypeMask and mActiveOutputVariables types and mask fit "
                   "into 32 bits each");
     state->mDrawBufferTypeMask.from_ulong(stream.readInt<uint32_t>());
-    state->mActiveOutputVariables = stream.readInt<uint32_t>();
+    state->mActiveOutputVariables = stream.readInt<gl::DrawBufferMask>();
 
     unsigned int samplerRangeLow  = stream.readInt<unsigned int>();
     unsigned int samplerRangeHigh = stream.readInt<unsigned int>();
     state->mSamplerUniformRange   = RangeUI(samplerRangeLow, samplerRangeHigh);
     unsigned int samplerCount = stream.readInt<unsigned int>();
     for (unsigned int samplerIndex = 0; samplerIndex < samplerCount; ++samplerIndex)
     {
-        GLenum textureType  = stream.readInt<GLenum>();
+        TextureType textureType = stream.readEnum<TextureType>();
         size_t bindingCount = stream.readInt<size_t>();
         bool unreferenced   = stream.readBool();
         state->mSamplerBindings.emplace_back(
             SamplerBinding(textureType, bindingCount, unreferenced));
     }
 
     unsigned int imageRangeLow  = stream.readInt<unsigned int>();
     unsigned int imageRangeHigh = stream.readInt<unsigned int>();
@@ -415,18 +424,21 @@ LinkResult MemoryProgramCache::Deseriali
         }
         state->mImageBindings.emplace_back(imageBinding);
     }
 
     unsigned int atomicCounterRangeLow  = stream.readInt<unsigned int>();
     unsigned int atomicCounterRangeHigh = stream.readInt<unsigned int>();
     state->mAtomicCounterUniformRange   = RangeUI(atomicCounterRangeLow, atomicCounterRangeHigh);
 
-    static_assert(SHADER_TYPE_MAX <= sizeof(unsigned long) * 8, "Too many shader types");
-    state->mLinkedShaderStages = stream.readInt<unsigned long>();
+    static_assert(static_cast<unsigned long>(ShaderType::EnumCount) <= sizeof(unsigned long) * 8,
+                  "Too many shader types");
+    state->mLinkedShaderStages = stream.readInt<gl::ShaderBitSet>();
+
+    state->updateTransformFeedbackStrides();
 
     return program->getImplementation()->load(context, infoLog, &stream);
 }
 
 // static
 void MemoryProgramCache::Serialize(const Context *context,
                                    const gl::Program *program,
                                    angle::MemoryBuffer *binaryOut)
@@ -572,17 +584,17 @@ void MemoryProgramCache::Serialize(const
     stream.writeInt(static_cast<int>(state.mActiveOutputVariables.to_ulong()));
 
     stream.writeInt(state.getSamplerUniformRange().low());
     stream.writeInt(state.getSamplerUniformRange().high());
 
     stream.writeInt(state.getSamplerBindings().size());
     for (const auto &samplerBinding : state.getSamplerBindings())
     {
-        stream.writeInt(samplerBinding.textureType);
+        stream.writeEnum(samplerBinding.textureType);
         stream.writeInt(samplerBinding.boundTextureUnits.size());
         stream.writeInt(samplerBinding.unreferenced);
     }
 
     stream.writeInt(state.getImageUniformRange().low());
     stream.writeInt(state.getImageUniformRange().high());
 
     stream.writeInt(state.getImageBindings().size());
@@ -607,24 +619,22 @@ void MemoryProgramCache::Serialize(const
     memcpy(binaryOut->data(), stream.data(), stream.length());
 }
 
 // static
 void MemoryProgramCache::ComputeHash(const Context *context,
                                      const Program *program,
                                      ProgramHash *hashOut)
 {
-    const Shader *vertexShader   = program->getAttachedVertexShader();
-    const Shader *fragmentShader = program->getAttachedFragmentShader();
-    const Shader *computeShader  = program->getAttachedComputeShader();
-    const Shader *geometryShader = program->getAttachedGeometryShader();
-
     // Compute the program hash. Start with the shader hashes and resource strings.
     HashStream hashStream;
-    hashStream << vertexShader << fragmentShader << computeShader << geometryShader;
+    for (ShaderType shaderType : AllShaderTypes())
+    {
+        hashStream << program->getAttachedShader(shaderType);
+    }
 
     // Add some ANGLE metadata and Context properties, such as version and back-end.
     hashStream << ANGLE_COMMIT_HASH << context->getClientMajorVersion()
                << context->getClientMinorVersion() << context->getString(GL_RENDERER);
 
     // Hash pre-link program properties.
     hashStream << program->getAttributeBindings() << program->getUniformLocationBindings()
                << program->getFragmentInputBindings()
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Observer.cpp
@@ -0,0 +1,167 @@
+//
+// 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.
+//
+// Observer:
+//   Implements the Observer pattern for sending state change notifications
+//   from Subject objects to dependent Observer objects.
+//
+//   See design document:
+//   https://docs.google.com/document/d/15Edfotqg6_l1skTEL8ADQudF_oIdNa7i8Po43k6jMd4/
+
+#include "libANGLE/Observer.h"
+
+#include <algorithm>
+
+#include "common/debug.h"
+
+namespace angle
+{
+namespace
+{
+template <typename HaystackT, typename NeedleT>
+bool IsInContainer(const HaystackT &haystack, const NeedleT &needle)
+{
+    return std::find(haystack.begin(), haystack.end(), needle) != haystack.end();
+}
+}  // anonymous namespace
+
+// Observer implementation.
+ObserverInterface::~ObserverInterface() = default;
+
+// Subject implementation.
+Subject::Subject()
+{
+}
+
+Subject::~Subject()
+{
+    resetObservers();
+}
+
+bool Subject::hasObservers() const
+{
+    return !mFastObservers.empty();
+}
+
+void Subject::addObserver(ObserverBinding *observer)
+{
+    ASSERT(!IsInContainer(mFastObservers, observer) && !IsInContainer(mSlowObservers, observer));
+
+    if (!mFastObservers.full())
+    {
+        mFastObservers.push_back(observer);
+    }
+    else
+    {
+        mSlowObservers.push_back(observer);
+    }
+}
+
+void Subject::removeObserver(ObserverBinding *observer)
+{
+    auto iter = std::find(mFastObservers.begin(), mFastObservers.end(), observer);
+    if (iter != mFastObservers.end())
+    {
+        size_t index = iter - mFastObservers.begin();
+        std::swap(mFastObservers[index], mFastObservers[mFastObservers.size() - 1]);
+        mFastObservers.resize(mFastObservers.size() - 1);
+        if (!mSlowObservers.empty())
+        {
+            mFastObservers.push_back(mSlowObservers.back());
+            mSlowObservers.pop_back();
+            ASSERT(mFastObservers.full());
+        }
+    }
+    else
+    {
+        auto slowIter = std::find(mSlowObservers.begin(), mSlowObservers.end(), observer);
+        ASSERT(slowIter != mSlowObservers.end());
+        mSlowObservers.erase(slowIter);
+    }
+}
+
+void Subject::onStateChange(const gl::Context *context, SubjectMessage message) const
+{
+    if (mFastObservers.empty())
+        return;
+
+    for (const angle::ObserverBinding *receiver : mFastObservers)
+    {
+        receiver->onStateChange(context, message);
+    }
+
+    for (const angle::ObserverBinding *receiver : mSlowObservers)
+    {
+        receiver->onStateChange(context, message);
+    }
+}
+
+void Subject::resetObservers()
+{
+    for (angle::ObserverBinding *observer : mFastObservers)
+    {
+        observer->onSubjectReset();
+    }
+    mFastObservers.clear();
+
+    for (angle::ObserverBinding *observer : mSlowObservers)
+    {
+        observer->onSubjectReset();
+    }
+    mSlowObservers.clear();
+}
+
+// ObserverBinding implementation.
+ObserverBinding::ObserverBinding(ObserverInterface *observer, SubjectIndex index)
+    : mSubject(nullptr), mObserver(observer), mIndex(index)
+{
+    ASSERT(observer);
+}
+
+ObserverBinding::~ObserverBinding()
+{
+    reset();
+}
+
+ObserverBinding::ObserverBinding(const ObserverBinding &other) = default;
+
+ObserverBinding &ObserverBinding::operator=(const ObserverBinding &other) = default;
+
+void ObserverBinding::bind(Subject *subject)
+{
+    ASSERT(mObserver);
+    if (mSubject)
+    {
+        mSubject->removeObserver(this);
+    }
+
+    mSubject = subject;
+
+    if (mSubject)
+    {
+        mSubject->addObserver(this);
+    }
+}
+
+void ObserverBinding::reset()
+{
+    bind(nullptr);
+}
+
+void ObserverBinding::onStateChange(const gl::Context *context, SubjectMessage message) const
+{
+    mObserver->onSubjectStateChange(context, mIndex, message);
+}
+
+void ObserverBinding::onSubjectReset()
+{
+    mSubject = nullptr;
+}
+
+const Subject *ObserverBinding::getSubject() const
+{
+    return mSubject;
+}
+}  // namespace angle
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Observer.h
@@ -0,0 +1,96 @@
+//
+// 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.
+//
+// Observer:
+//   Implements the Observer pattern for sending state change notifications
+//   from Subject objects to dependent Observer objects.
+//
+//   See design document:
+//   https://docs.google.com/document/d/15Edfotqg6_l1skTEL8ADQudF_oIdNa7i8Po43k6jMd4/
+
+#ifndef LIBANGLE_OBSERVER_H_
+#define LIBANGLE_OBSERVER_H_
+
+#include "common/FixedVector.h"
+#include "common/angleutils.h"
+
+namespace gl
+{
+class Context;
+}  // namespace gl
+
+namespace angle
+{
+
+using SubjectIndex = size_t;
+
+enum class SubjectMessage
+{
+    CONTENTS_CHANGED,
+    STORAGE_CHANGED,
+    DEPENDENT_DIRTY_BITS,
+};
+
+// The observing class inherits from this interface class.
+class ObserverInterface
+{
+  public:
+    virtual ~ObserverInterface();
+    virtual void onSubjectStateChange(const gl::Context *context,
+                                      SubjectIndex index,
+                                      SubjectMessage message) = 0;
+};
+
+class ObserverBinding;
+
+// Maintains a list of observer bindings. Sends update messages to the observer.
+class Subject : NonCopyable
+{
+  public:
+    Subject();
+    virtual ~Subject();
+
+    void onStateChange(const gl::Context *context, SubjectMessage message) const;
+    bool hasObservers() const;
+    void resetObservers();
+
+  private:
+    // Only the ObserverBinding class should add or remove observers.
+    friend class ObserverBinding;
+    void addObserver(ObserverBinding *observer);
+    void removeObserver(ObserverBinding *observer);
+
+    // Keep a short list of observers so we can allocate/free them quickly. But since we support
+    // unlimited bindings, have a spill-over list of that uses dynamic allocation.
+    static constexpr size_t kMaxFixedObservers = 8;
+    angle::FixedVector<ObserverBinding *, kMaxFixedObservers> mFastObservers;
+    std::vector<ObserverBinding *> mSlowObservers;
+};
+
+// Keeps a binding between a Subject and Observer, with a specific subject index.
+class ObserverBinding final
+{
+  public:
+    ObserverBinding(ObserverInterface *observer, SubjectIndex index);
+    ~ObserverBinding();
+    ObserverBinding(const ObserverBinding &other);
+    ObserverBinding &operator=(const ObserverBinding &other);
+
+    void bind(Subject *subject);
+    void reset();
+    void onStateChange(const gl::Context *context, SubjectMessage message) const;
+    void onSubjectReset();
+
+    const Subject *getSubject() const;
+
+  private:
+    Subject *mSubject;
+    ObserverInterface *mObserver;
+    SubjectIndex mIndex;
+};
+
+}  // namespace angle
+
+#endif  // LIBANGLE_OBSERVER_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/PackedGLEnums.cpp
@@ -0,0 +1,196 @@
+// 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.
+//
+// PackedGLEnums.cpp:
+//   Declares ANGLE-specific enums classes for GLEnum and functions operating
+//   on them.
+
+#include "libANGLE/PackedGLEnums.h"
+
+#include "common/utilities.h"
+
+namespace gl
+{
+
+TextureType TextureTargetToType(TextureTarget target)
+{
+    switch (target)
+    {
+        case TextureTarget::CubeMapNegativeX:
+        case TextureTarget::CubeMapNegativeY:
+        case TextureTarget::CubeMapNegativeZ:
+        case TextureTarget::CubeMapPositiveX:
+        case TextureTarget::CubeMapPositiveY:
+        case TextureTarget::CubeMapPositiveZ:
+            return TextureType::CubeMap;
+        case TextureTarget::External:
+            return TextureType::External;
+        case TextureTarget::Rectangle:
+            return TextureType::Rectangle;
+        case TextureTarget::_2D:
+            return TextureType::_2D;
+        case TextureTarget::_2DArray:
+            return TextureType::_2DArray;
+        case TextureTarget::_2DMultisample:
+            return TextureType::_2DMultisample;
+        case TextureTarget::_3D:
+            return TextureType::_3D;
+        default:
+            UNREACHABLE();
+            return TextureType::InvalidEnum;
+    }
+}
+
+TextureTarget NonCubeTextureTypeToTarget(TextureType type)
+{
+    switch (type)
+    {
+        case TextureType::External:
+            return TextureTarget::External;
+        case TextureType::Rectangle:
+            return TextureTarget::Rectangle;
+        case TextureType::_2D:
+            return TextureTarget::_2D;
+        case TextureType::_2DArray:
+            return TextureTarget::_2DArray;
+        case TextureType::_2DMultisample:
+            return TextureTarget::_2DMultisample;
+        case TextureType::_3D:
+            return TextureTarget::_3D;
+        default:
+            UNREACHABLE();
+            return TextureTarget::InvalidEnum;
+    }
+}
+
+// Check that we can do arithmetic on TextureTarget to convert from / to cube map faces
+static_assert(static_cast<uint8_t>(TextureTarget::CubeMapNegativeX) -
+                      static_cast<uint8_t>(TextureTarget::CubeMapPositiveX) ==
+                  1u,
+              "");
+static_assert(static_cast<uint8_t>(TextureTarget::CubeMapPositiveY) -
+                      static_cast<uint8_t>(TextureTarget::CubeMapPositiveX) ==
+                  2u,
+              "");
+static_assert(static_cast<uint8_t>(TextureTarget::CubeMapNegativeY) -
+                      static_cast<uint8_t>(TextureTarget::CubeMapPositiveX) ==
+                  3u,
+              "");
+static_assert(static_cast<uint8_t>(TextureTarget::CubeMapPositiveZ) -
+                      static_cast<uint8_t>(TextureTarget::CubeMapPositiveX) ==
+                  4u,
+              "");
+static_assert(static_cast<uint8_t>(TextureTarget::CubeMapNegativeZ) -
+                      static_cast<uint8_t>(TextureTarget::CubeMapPositiveX) ==
+                  5u,
+              "");
+
+TextureTarget CubeFaceIndexToTextureTarget(size_t face)
+{
+    ASSERT(face < 6u);
+    return static_cast<TextureTarget>(static_cast<uint8_t>(TextureTarget::CubeMapPositiveX) + face);
+}
+
+size_t CubeMapTextureTargetToFaceIndex(TextureTarget target)
+{
+    ASSERT(TextureTargetToType(target) == TextureType::CubeMap);
+    return static_cast<uint8_t>(target) - static_cast<uint8_t>(TextureTarget::CubeMapPositiveX);
+}
+
+TextureType SamplerTypeToTextureType(GLenum samplerType)
+{
+    switch (samplerType)
+    {
+        case GL_SAMPLER_2D:
+        case GL_INT_SAMPLER_2D:
+        case GL_UNSIGNED_INT_SAMPLER_2D:
+        case GL_SAMPLER_2D_SHADOW:
+            return TextureType::_2D;
+
+        case GL_SAMPLER_EXTERNAL_OES:
+            return TextureType::External;
+
+        case GL_SAMPLER_CUBE:
+        case GL_INT_SAMPLER_CUBE:
+        case GL_UNSIGNED_INT_SAMPLER_CUBE:
+        case GL_SAMPLER_CUBE_SHADOW:
+            return TextureType::CubeMap;
+
+        case GL_SAMPLER_2D_ARRAY:
+        case GL_INT_SAMPLER_2D_ARRAY:
+        case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+        case GL_SAMPLER_2D_ARRAY_SHADOW:
+            return TextureType::_2DArray;
+
+        case GL_SAMPLER_3D:
+        case GL_INT_SAMPLER_3D:
+        case GL_UNSIGNED_INT_SAMPLER_3D:
+            return TextureType::_3D;
+
+        case GL_SAMPLER_2D_MULTISAMPLE:
+        case GL_INT_SAMPLER_2D_MULTISAMPLE:
+        case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
+            return TextureType::_2DMultisample;
+
+        case GL_SAMPLER_2D_RECT_ANGLE:
+            return TextureType::Rectangle;
+
+        default:
+            UNREACHABLE();
+            return TextureType::InvalidEnum;
+    }
+}
+
+}  // namespace gl
+
+namespace egl_gl
+{
+
+gl::TextureTarget EGLCubeMapTargetToCubeMapTarget(EGLenum eglTarget)
+{
+    ASSERT(egl::IsCubeMapTextureTarget(eglTarget));
+    return gl::CubeFaceIndexToTextureTarget(egl::CubeMapTextureTargetToLayerIndex(eglTarget));
+}
+
+gl::TextureTarget EGLImageTargetToTextureTarget(EGLenum eglTarget)
+{
+    switch (eglTarget)
+    {
+        case EGL_GL_TEXTURE_2D_KHR:
+            return gl::TextureTarget::_2D;
+
+        case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
+        case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
+        case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
+        case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
+        case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
+        case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
+            return EGLCubeMapTargetToCubeMapTarget(eglTarget);
+
+        case EGL_GL_TEXTURE_3D_KHR:
+            return gl::TextureTarget::_3D;
+
+        default:
+            UNREACHABLE();
+            return gl::TextureTarget::InvalidEnum;
+    }
+}
+
+gl::TextureType EGLTextureTargetToTextureType(EGLenum eglTarget)
+{
+    switch (eglTarget)
+    {
+        case EGL_TEXTURE_2D:
+            return gl::TextureType::_2D;
+
+        case EGL_TEXTURE_RECTANGLE_ANGLE:
+            return gl::TextureType::Rectangle;
+
+        default:
+            UNREACHABLE();
+            return gl::TextureType::InvalidEnum;
+    }
+}
+
+}  // namespace egl_gl
--- a/gfx/angle/checkout/src/libANGLE/PackedGLEnums.h
+++ b/gfx/angle/checkout/src/libANGLE/PackedGLEnums.h
@@ -10,16 +10,18 @@
 #define LIBANGLE_PACKEDGLENUMS_H_
 
 #include "libANGLE/PackedGLEnums_autogen.h"
 
 #include <array>
 #include <bitset>
 #include <cstddef>
 
+#include <EGL/egl.h>
+
 #include "common/bitset_utils.h"
 
 namespace angle
 {
 
 // Return the number of elements of a packed enum, including the InvalidEnum element.
 template <typename E>
 constexpr size_t EnumSize()
@@ -126,9 +128,61 @@ class PackedEnumMap
 
 // PackedEnumBitSetE> is like an std::bitset<E::EnumCount> but is indexed with enum values. It
 // implements the std::bitset interface except with enum values instead of indices.
 template <typename E>
 using PackedEnumBitSet = BitSetT<EnumSize<E>(), uint32_t, E>;
 
 }  // namespace angle
 
+namespace gl
+{
+
+TextureType TextureTargetToType(TextureTarget target);
+TextureTarget NonCubeTextureTypeToTarget(TextureType type);
+
+TextureTarget CubeFaceIndexToTextureTarget(size_t face);
+size_t CubeMapTextureTargetToFaceIndex(TextureTarget target);
+
+constexpr TextureTarget kCubeMapTextureTargetMin = TextureTarget::CubeMapPositiveX;
+constexpr TextureTarget kCubeMapTextureTargetMax = TextureTarget::CubeMapNegativeZ;
+constexpr TextureTarget kAfterCubeMapTextureTargetMax =
+    static_cast<TextureTarget>(static_cast<uint8_t>(kCubeMapTextureTargetMax) + 1);
+struct AllCubeFaceTextureTargets
+{
+    angle::EnumIterator<TextureTarget> begin() const { return kCubeMapTextureTargetMin; }
+    angle::EnumIterator<TextureTarget> end() const { return kAfterCubeMapTextureTargetMax; }
+};
+
+constexpr ShaderType kGLES2ShaderTypeMin = ShaderType::Vertex;
+constexpr ShaderType kGLES2ShaderTypeMax = ShaderType::Fragment;
+constexpr ShaderType kAfterGLES2ShaderTypeMax =
+    static_cast<ShaderType>(static_cast<uint8_t>(kGLES2ShaderTypeMax) + 1);
+struct AllGLES2ShaderTypes
+{
+    angle::EnumIterator<ShaderType> begin() const { return kGLES2ShaderTypeMin; }
+    angle::EnumIterator<ShaderType> end() const { return kAfterGLES2ShaderTypeMax; }
+};
+
+constexpr ShaderType kShaderTypeMin = ShaderType::Vertex;
+constexpr ShaderType kShaderTypeMax = ShaderType::Compute;
+constexpr ShaderType kAfterShaderTypeMax =
+    static_cast<ShaderType>(static_cast<uint8_t>(kShaderTypeMax) + 1);
+struct AllShaderTypes
+{
+    angle::EnumIterator<ShaderType> begin() const { return kShaderTypeMin; }
+    angle::EnumIterator<ShaderType> end() const { return kAfterShaderTypeMax; }
+};
+
+using ShaderBitSet = angle::PackedEnumBitSet<ShaderType>;
+
+TextureType SamplerTypeToTextureType(GLenum samplerType);
+
+}  // namespace gl
+
+namespace egl_gl
+{
+gl::TextureTarget EGLCubeMapTargetToCubeMapTarget(EGLenum eglTarget);
+gl::TextureTarget EGLImageTargetToTextureTarget(EGLenum eglTarget);
+gl::TextureType EGLTextureTargetToTextureType(EGLenum eglTarget);
+}  // namespace egl_gl
+
 #endif  // LIBANGLE_PACKEDGLENUMS_H_
--- a/gfx/angle/checkout/src/libANGLE/PackedGLEnums_autogen.cpp
+++ b/gfx/angle/checkout/src/libANGLE/PackedGLEnums_autogen.cpp
@@ -11,16 +11,68 @@
 
 #include "libANGLE/PackedGLEnums_autogen.h"
 #include "common/debug.h"
 
 namespace gl
 {
 
 template <>
+AlphaTestFunc FromGLenum<AlphaTestFunc>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_ALWAYS:
+            return AlphaTestFunc::AlwaysPass;
+        case GL_EQUAL:
+            return AlphaTestFunc::Equal;
+        case GL_GEQUAL:
+            return AlphaTestFunc::Gequal;
+        case GL_GREATER:
+            return AlphaTestFunc::Greater;
+        case GL_LEQUAL:
+            return AlphaTestFunc::Lequal;
+        case GL_LESS:
+            return AlphaTestFunc::Less;
+        case GL_NEVER:
+            return AlphaTestFunc::Never;
+        case GL_NOTEQUAL:
+            return AlphaTestFunc::NotEqual;
+        default:
+            return AlphaTestFunc::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(AlphaTestFunc from)
+{
+    switch (from)
+    {
+        case AlphaTestFunc::AlwaysPass:
+            return GL_ALWAYS;
+        case AlphaTestFunc::Equal:
+            return GL_EQUAL;
+        case AlphaTestFunc::Gequal:
+            return GL_GEQUAL;
+        case AlphaTestFunc::Greater:
+            return GL_GREATER;
+        case AlphaTestFunc::Lequal:
+            return GL_LEQUAL;
+        case AlphaTestFunc::Less:
+            return GL_LESS;
+        case AlphaTestFunc::Never:
+            return GL_NEVER;
+        case AlphaTestFunc::NotEqual:
+            return GL_NOTEQUAL;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+template <>
 BufferBinding FromGLenum<BufferBinding>(GLenum from)
 {
     switch (from)
     {
         case GL_ARRAY_BUFFER:
             return BufferBinding::Array;
         case GL_ATOMIC_COUNTER_BUFFER:
             return BufferBinding::AtomicCounter;
@@ -166,9 +218,577 @@ GLenum ToGLenum(CullFaceMode from)
         case CullFaceMode::FrontAndBack:
             return GL_FRONT_AND_BACK;
         default:
             UNREACHABLE();
             return GL_NONE;
     }
 }
 
+template <>
+FogMode FromGLenum<FogMode>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_EXP:
+            return FogMode::Exp;
+        case GL_EXP2:
+            return FogMode::Exp2;
+        case GL_LINEAR:
+            return FogMode::Linear;
+        default:
+            return FogMode::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(FogMode from)
+{
+    switch (from)
+    {
+        case FogMode::Exp:
+            return GL_EXP;
+        case FogMode::Exp2:
+            return GL_EXP2;
+        case FogMode::Linear:
+            return GL_LINEAR;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+template <>
+HintSetting FromGLenum<HintSetting>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_DONT_CARE:
+            return HintSetting::DontCare;
+        case GL_FASTEST:
+            return HintSetting::Fastest;
+        case GL_NICEST:
+            return HintSetting::Nicest;
+        default:
+            return HintSetting::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(HintSetting from)
+{
+    switch (from)
+    {
+        case HintSetting::DontCare:
+            return GL_DONT_CARE;
+        case HintSetting::Fastest:
+            return GL_FASTEST;
+        case HintSetting::Nicest:
+            return GL_NICEST;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+template <>
+LogicalOperation FromGLenum<LogicalOperation>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_AND:
+            return LogicalOperation::And;
+        case GL_AND_INVERTED:
+            return LogicalOperation::AndInverted;
+        case GL_AND_REVERSE:
+            return LogicalOperation::AndReverse;
+        case GL_CLEAR:
+            return LogicalOperation::Clear;
+        case GL_COPY:
+            return LogicalOperation::Copy;
+        case GL_COPY_INVERTED:
+            return LogicalOperation::CopyInverted;
+        case GL_EQUIV:
+            return LogicalOperation::Equiv;
+        case GL_INVERT:
+            return LogicalOperation::Invert;
+        case GL_NAND:
+            return LogicalOperation::Nand;
+        case GL_NOOP:
+            return LogicalOperation::Noop;
+        case GL_NOR:
+            return LogicalOperation::Nor;
+        case GL_OR:
+            return LogicalOperation::Or;
+        case GL_OR_INVERTED:
+            return LogicalOperation::OrInverted;
+        case GL_OR_REVERSE:
+            return LogicalOperation::OrReverse;
+        case GL_SET:
+            return LogicalOperation::Set;
+        case GL_XOR:
+            return LogicalOperation::Xor;
+        default:
+            return LogicalOperation::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(LogicalOperation from)
+{
+    switch (from)
+    {
+        case LogicalOperation::And:
+            return GL_AND;
+        case LogicalOperation::AndInverted:
+            return GL_AND_INVERTED;
+        case LogicalOperation::AndReverse:
+            return GL_AND_REVERSE;
+        case LogicalOperation::Clear:
+            return GL_CLEAR;
+        case LogicalOperation::Copy:
+            return GL_COPY;
+        case LogicalOperation::CopyInverted:
+            return GL_COPY_INVERTED;
+        case LogicalOperation::Equiv:
+            return GL_EQUIV;
+        case LogicalOperation::Invert:
+            return GL_INVERT;
+        case LogicalOperation::Nand:
+            return GL_NAND;
+        case LogicalOperation::Noop:
+            return GL_NOOP;
+        case LogicalOperation::Nor:
+            return GL_NOR;
+        case LogicalOperation::Or:
+            return GL_OR;
+        case LogicalOperation::OrInverted:
+            return GL_OR_INVERTED;
+        case LogicalOperation::OrReverse:
+            return GL_OR_REVERSE;
+        case LogicalOperation::Set:
+            return GL_SET;
+        case LogicalOperation::Xor:
+            return GL_XOR;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+template <>
+MatrixType FromGLenum<MatrixType>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_MODELVIEW:
+            return MatrixType::Modelview;
+        case GL_PROJECTION:
+            return MatrixType::Projection;
+        case GL_TEXTURE:
+            return MatrixType::Texture;
+        default:
+            return MatrixType::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(MatrixType from)
+{
+    switch (from)
+    {
+        case MatrixType::Modelview:
+            return GL_MODELVIEW;
+        case MatrixType::Projection:
+            return GL_PROJECTION;
+        case MatrixType::Texture:
+            return GL_TEXTURE;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+template <>
+ShaderType FromGLenum<ShaderType>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_VERTEX_SHADER:
+            return ShaderType::Vertex;
+        case GL_FRAGMENT_SHADER:
+            return ShaderType::Fragment;
+        case GL_GEOMETRY_SHADER_EXT:
+            return ShaderType::Geometry;
+        case GL_COMPUTE_SHADER:
+            return ShaderType::Compute;
+        default:
+            return ShaderType::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(ShaderType from)
+{
+    switch (from)
+    {
+        case ShaderType::Vertex:
+            return GL_VERTEX_SHADER;
+        case ShaderType::Fragment:
+            return GL_FRAGMENT_SHADER;
+        case ShaderType::Geometry:
+            return GL_GEOMETRY_SHADER_EXT;
+        case ShaderType::Compute:
+            return GL_COMPUTE_SHADER;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+template <>
+ShadingModel FromGLenum<ShadingModel>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_FLAT:
+            return ShadingModel::Flat;
+        case GL_SMOOTH:
+            return ShadingModel::Smooth;
+        default:
+            return ShadingModel::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(ShadingModel from)
+{
+    switch (from)
+    {
+        case ShadingModel::Flat:
+            return GL_FLAT;
+        case ShadingModel::Smooth:
+            return GL_SMOOTH;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+template <>
+TextureCombine FromGLenum<TextureCombine>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_ADD:
+            return TextureCombine::Add;
+        case GL_ADD_SIGNED:
+            return TextureCombine::AddSigned;
+        case GL_DOT3_RGB:
+            return TextureCombine::Dot3Rgb;
+        case GL_DOT3_RGBA:
+            return TextureCombine::Dot3Rgba;
+        case GL_INTERPOLATE:
+            return TextureCombine::Interpolate;
+        case GL_MODULATE:
+            return TextureCombine::Modulate;
+        case GL_REPLACE:
+            return TextureCombine::Replace;
+        case GL_SUBTRACT:
+            return TextureCombine::Subtract;
+        default:
+            return TextureCombine::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(TextureCombine from)
+{
+    switch (from)
+    {
+        case TextureCombine::Add:
+            return GL_ADD;
+        case TextureCombine::AddSigned:
+            return GL_ADD_SIGNED;
+        case TextureCombine::Dot3Rgb:
+            return GL_DOT3_RGB;
+        case TextureCombine::Dot3Rgba:
+            return GL_DOT3_RGBA;
+        case TextureCombine::Interpolate:
+            return GL_INTERPOLATE;
+        case TextureCombine::Modulate:
+            return GL_MODULATE;
+        case TextureCombine::Replace:
+            return GL_REPLACE;
+        case TextureCombine::Subtract:
+            return GL_SUBTRACT;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+template <>
+TextureEnvMode FromGLenum<TextureEnvMode>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_ADD:
+            return TextureEnvMode::Add;
+        case GL_BLEND:
+            return TextureEnvMode::Blend;
+        case GL_COMBINE:
+            return TextureEnvMode::Combine;
+        case GL_DECAL:
+            return TextureEnvMode::Decal;
+        case GL_MODULATE:
+            return TextureEnvMode::Modulate;
+        case GL_REPLACE:
+            return TextureEnvMode::Replace;
+        default:
+            return TextureEnvMode::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(TextureEnvMode from)
+{
+    switch (from)
+    {
+        case TextureEnvMode::Add:
+            return GL_ADD;
+        case TextureEnvMode::Blend:
+            return GL_BLEND;
+        case TextureEnvMode::Combine:
+            return GL_COMBINE;
+        case TextureEnvMode::Decal:
+            return GL_DECAL;
+        case TextureEnvMode::Modulate:
+            return GL_MODULATE;
+        case TextureEnvMode::Replace:
+            return GL_REPLACE;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+template <>
+TextureOp FromGLenum<TextureOp>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_ONE_MINUS_SRC_ALPHA:
+            return TextureOp::OneMinusSrcAlpha;
+        case GL_ONE_MINUS_SRC_COLOR:
+            return TextureOp::OneMinusSrcColor;
+        case GL_SRC_ALPHA:
+            return TextureOp::SrcAlpha;
+        case GL_SRC_COLOR:
+            return TextureOp::SrcColor;
+        default:
+            return TextureOp::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(TextureOp from)
+{
+    switch (from)
+    {
+        case TextureOp::OneMinusSrcAlpha:
+            return GL_ONE_MINUS_SRC_ALPHA;
+        case TextureOp::OneMinusSrcColor:
+            return GL_ONE_MINUS_SRC_COLOR;
+        case TextureOp::SrcAlpha:
+            return GL_SRC_ALPHA;
+        case TextureOp::SrcColor:
+            return GL_SRC_COLOR;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+template <>
+TextureSrc FromGLenum<TextureSrc>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_CONSTANT:
+            return TextureSrc::Constant;
+        case GL_PREVIOUS:
+            return TextureSrc::Previous;
+        case GL_PRIMARY_COLOR:
+            return TextureSrc::PrimaryColor;
+        case GL_TEXTURE:
+            return TextureSrc::Texture;
+        default:
+            return TextureSrc::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(TextureSrc from)
+{
+    switch (from)
+    {
+        case TextureSrc::Constant:
+            return GL_CONSTANT;
+        case TextureSrc::Previous:
+            return GL_PREVIOUS;
+        case TextureSrc::PrimaryColor:
+            return GL_PRIMARY_COLOR;
+        case TextureSrc::Texture:
+            return GL_TEXTURE;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+template <>
+TextureTarget FromGLenum<TextureTarget>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_TEXTURE_2D:
+            return TextureTarget::_2D;
+        case GL_TEXTURE_2D_ARRAY:
+            return TextureTarget::_2DArray;
+        case GL_TEXTURE_2D_MULTISAMPLE:
+            return TextureTarget::_2DMultisample;
+        case GL_TEXTURE_3D:
+            return TextureTarget::_3D;
+        case GL_TEXTURE_EXTERNAL_OES:
+            return TextureTarget::External;
+        case GL_TEXTURE_RECTANGLE_ANGLE:
+            return TextureTarget::Rectangle;
+        case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+            return TextureTarget::CubeMapPositiveX;
+        case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+            return TextureTarget::CubeMapNegativeX;
+        case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+            return TextureTarget::CubeMapPositiveY;
+        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+            return TextureTarget::CubeMapNegativeY;
+        case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+            return TextureTarget::CubeMapPositiveZ;
+        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+            return TextureTarget::CubeMapNegativeZ;
+        default:
+            return TextureTarget::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(TextureTarget from)
+{
+    switch (from)
+    {
+        case TextureTarget::_2D:
+            return GL_TEXTURE_2D;
+        case TextureTarget::_2DArray:
+            return GL_TEXTURE_2D_ARRAY;
+        case TextureTarget::_2DMultisample:
+            return GL_TEXTURE_2D_MULTISAMPLE;
+        case TextureTarget::_3D:
+            return GL_TEXTURE_3D;
+        case TextureTarget::External:
+            return GL_TEXTURE_EXTERNAL_OES;
+        case TextureTarget::Rectangle:
+            return GL_TEXTURE_RECTANGLE_ANGLE;
+        case TextureTarget::CubeMapPositiveX:
+            return GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+        case TextureTarget::CubeMapNegativeX:
+            return GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
+        case TextureTarget::CubeMapPositiveY:
+            return GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
+        case TextureTarget::CubeMapNegativeY:
+            return GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
+        case TextureTarget::CubeMapPositiveZ:
+            return GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
+        case TextureTarget::CubeMapNegativeZ:
+            return GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+template <>
+TextureType FromGLenum<TextureType>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_TEXTURE_2D:
+            return TextureType::_2D;
+        case GL_TEXTURE_2D_ARRAY:
+            return TextureType::_2DArray;
+        case GL_TEXTURE_2D_MULTISAMPLE:
+            return TextureType::_2DMultisample;
+        case GL_TEXTURE_3D:
+            return TextureType::_3D;
+        case GL_TEXTURE_EXTERNAL_OES:
+            return TextureType::External;
+        case GL_TEXTURE_RECTANGLE_ANGLE:
+            return TextureType::Rectangle;
+        case GL_TEXTURE_CUBE_MAP:
+            return TextureType::CubeMap;
+        default:
+            return TextureType::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(TextureType from)
+{
+    switch (from)
+    {
+        case TextureType::_2D:
+            return GL_TEXTURE_2D;
+        case TextureType::_2DArray:
+            return GL_TEXTURE_2D_ARRAY;
+        case TextureType::_2DMultisample:
+            return GL_TEXTURE_2D_MULTISAMPLE;
+        case TextureType::_3D:
+            return GL_TEXTURE_3D;
+        case TextureType::External:
+            return GL_TEXTURE_EXTERNAL_OES;
+        case TextureType::Rectangle:
+            return GL_TEXTURE_RECTANGLE_ANGLE;
+        case TextureType::CubeMap:
+            return GL_TEXTURE_CUBE_MAP;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+template <>
+VertexArrayType FromGLenum<VertexArrayType>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_COLOR_ARRAY:
+            return VertexArrayType::Color;
+        case GL_NORMAL_ARRAY:
+            return VertexArrayType::Normal;
+        case GL_POINT_SIZE_ARRAY_OES:
+            return VertexArrayType::PointSize;
+        case GL_TEXTURE_COORD_ARRAY:
+            return VertexArrayType::TextureCoord;
+        case GL_VERTEX_ARRAY:
+            return VertexArrayType::Vertex;
+        default:
+            return VertexArrayType::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(VertexArrayType from)
+{
+    switch (from)
+    {
+        case VertexArrayType::Color:
+            return GL_COLOR_ARRAY;
+        case VertexArrayType::Normal:
+            return GL_NORMAL_ARRAY;
+        case VertexArrayType::PointSize:
+            return GL_POINT_SIZE_ARRAY_OES;
+        case VertexArrayType::TextureCoord:
+            return GL_TEXTURE_COORD_ARRAY;
+        case VertexArrayType::Vertex:
+            return GL_VERTEX_ARRAY;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
 }  // namespace gl
--- a/gfx/angle/checkout/src/libANGLE/PackedGLEnums_autogen.h
+++ b/gfx/angle/checkout/src/libANGLE/PackedGLEnums_autogen.h
@@ -17,16 +17,35 @@
 #include <cstdint>
 
 namespace gl
 {
 
 template <typename Enum>
 Enum FromGLenum(GLenum from);
 
+enum class AlphaTestFunc : uint8_t
+{
+    AlwaysPass = 0,
+    Equal      = 1,
+    Gequal     = 2,
+    Greater    = 3,
+    Lequal     = 4,
+    Less       = 5,
+    Never      = 6,
+    NotEqual   = 7,
+
+    InvalidEnum = 8,
+    EnumCount   = 8,
+};
+
+template <>
+AlphaTestFunc FromGLenum<AlphaTestFunc>(GLenum from);
+GLenum ToGLenum(AlphaTestFunc from);
+
 enum class BufferBinding : uint8_t
 {
     Array             = 0,
     AtomicCounter     = 1,
     CopyRead          = 2,
     CopyWrite         = 3,
     DispatchIndirect  = 4,
     DrawIndirect      = 5,
@@ -74,11 +93,231 @@ enum class CullFaceMode : uint8_t
     InvalidEnum = 3,
     EnumCount   = 3,
 };
 
 template <>
 CullFaceMode FromGLenum<CullFaceMode>(GLenum from);
 GLenum ToGLenum(CullFaceMode from);
 
+enum class FogMode : uint8_t
+{
+    Exp    = 0,
+    Exp2   = 1,
+    Linear = 2,
+
+    InvalidEnum = 3,
+    EnumCount   = 3,
+};
+
+template <>
+FogMode FromGLenum<FogMode>(GLenum from);
+GLenum ToGLenum(FogMode from);
+
+enum class HintSetting : uint8_t
+{
+    DontCare = 0,
+    Fastest  = 1,
+    Nicest   = 2,
+
+    InvalidEnum = 3,
+    EnumCount   = 3,
+};
+
+template <>
+HintSetting FromGLenum<HintSetting>(GLenum from);
+GLenum ToGLenum(HintSetting from);
+
+enum class LogicalOperation : uint8_t
+{
+    And          = 0,
+    AndInverted  = 1,
+    AndReverse   = 2,
+    Clear        = 3,
+    Copy         = 4,
+    CopyInverted = 5,
+    Equiv        = 6,
+    Invert       = 7,
+    Nand         = 8,
+    Noop         = 9,
+    Nor          = 10,
+    Or           = 11,
+    OrInverted   = 12,
+    OrReverse    = 13,
+    Set          = 14,
+    Xor          = 15,
+
+    InvalidEnum = 16,
+    EnumCount   = 16,
+};
+
+template <>
+LogicalOperation FromGLenum<LogicalOperation>(GLenum from);
+GLenum ToGLenum(LogicalOperation from);
+
+enum class MatrixType : uint8_t
+{
+    Modelview  = 0,
+    Projection = 1,
+    Texture    = 2,
+
+    InvalidEnum = 3,
+    EnumCount   = 3,
+};
+
+template <>
+MatrixType FromGLenum<MatrixType>(GLenum from);
+GLenum ToGLenum(MatrixType from);
+
+enum class ShaderType : uint8_t
+{
+    Vertex   = 0,
+    Fragment = 1,
+    Geometry = 2,
+    Compute  = 3,
+
+    InvalidEnum = 4,
+    EnumCount   = 4,
+};
+
+template <>
+ShaderType FromGLenum<ShaderType>(GLenum from);
+GLenum ToGLenum(ShaderType from);
+
+enum class ShadingModel : uint8_t
+{
+    Flat   = 0,
+    Smooth = 1,
+
+    InvalidEnum = 2,
+    EnumCount   = 2,
+};
+
+template <>
+ShadingModel FromGLenum<ShadingModel>(GLenum from);
+GLenum ToGLenum(ShadingModel from);
+
+enum class TextureCombine : uint8_t
+{
+    Add         = 0,
+    AddSigned   = 1,
+    Dot3Rgb     = 2,
+    Dot3Rgba    = 3,
+    Interpolate = 4,
+    Modulate    = 5,
+    Replace     = 6,
+    Subtract    = 7,
+
+    InvalidEnum = 8,
+    EnumCount   = 8,
+};
+
+template <>
+TextureCombine FromGLenum<TextureCombine>(GLenum from);
+GLenum ToGLenum(TextureCombine from);
+
+enum class TextureEnvMode : uint8_t
+{
+    Add      = 0,
+    Blend    = 1,
+    Combine  = 2,
+    Decal    = 3,
+    Modulate = 4,
+    Replace  = 5,
+
+    InvalidEnum = 6,
+    EnumCount   = 6,
+};
+
+template <>
+TextureEnvMode FromGLenum<TextureEnvMode>(GLenum from);
+GLenum ToGLenum(TextureEnvMode from);
+
+enum class TextureOp : uint8_t
+{
+    OneMinusSrcAlpha = 0,
+    OneMinusSrcColor = 1,
+    SrcAlpha         = 2,
+    SrcColor         = 3,
+
+    InvalidEnum = 4,
+    EnumCount   = 4,
+};
+
+template <>
+TextureOp FromGLenum<TextureOp>(GLenum from);
+GLenum ToGLenum(TextureOp from);
+
+enum class TextureSrc : uint8_t
+{
+    Constant     = 0,
+    Previous     = 1,
+    PrimaryColor = 2,
+    Texture      = 3,
+
+    InvalidEnum = 4,
+    EnumCount   = 4,
+};
+
+template <>
+TextureSrc FromGLenum<TextureSrc>(GLenum from);
+GLenum ToGLenum(TextureSrc from);
+
+enum class TextureTarget : uint8_t
+{
+    _2D              = 0,
+    _2DArray         = 1,
+    _2DMultisample   = 2,
+    _3D              = 3,
+    External         = 4,
+    Rectangle        = 5,
+    CubeMapPositiveX = 6,
+    CubeMapNegativeX = 7,
+    CubeMapPositiveY = 8,
+    CubeMapNegativeY = 9,
+    CubeMapPositiveZ = 10,
+    CubeMapNegativeZ = 11,
+
+    InvalidEnum = 12,
+    EnumCount   = 12,
+};
+
+template <>
+TextureTarget FromGLenum<TextureTarget>(GLenum from);
+GLenum ToGLenum(TextureTarget from);
+
+enum class TextureType : uint8_t
+{
+    _2D            = 0,
+    _2DArray       = 1,
+    _2DMultisample = 2,
+    _3D            = 3,
+    External       = 4,
+    Rectangle      = 5,
+    CubeMap        = 6,
+
+    InvalidEnum = 7,
+    EnumCount   = 7,
+};
+
+template <>
+TextureType FromGLenum<TextureType>(GLenum from);
+GLenum ToGLenum(TextureType from);
+
+enum class VertexArrayType : uint8_t
+{
+    Color        = 0,
+    Normal       = 1,
+    PointSize    = 2,
+    TextureCoord = 3,
+    Vertex       = 4,
+
+    InvalidEnum = 5,
+    EnumCount   = 5,
+};
+
+template <>
+VertexArrayType FromGLenum<VertexArrayType>(GLenum from);
+GLenum ToGLenum(VertexArrayType from);
+
 }  // namespace gl
 
 #endif  // LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
--- a/gfx/angle/checkout/src/libANGLE/Program.cpp
+++ b/gfx/angle/checkout/src/libANGLE/Program.cpp
@@ -200,25 +200,25 @@ bool IncludeSameArrayElement(const std::
             (subscripts.empty() || arrayIndices.empty() || subscripts == arrayIndices))
         {
             return true;
         }
     }
     return false;
 }
 
-bool validateInterfaceBlocksCount(GLuint maxInterfaceBlocks,
+bool ValidateInterfaceBlocksCount(GLuint maxInterfaceBlocks,
                                   const std::vector<sh::InterfaceBlock> &interfaceBlocks,
                                   const std::string &errorMessage,
                                   InfoLog &infoLog)
 {
     GLuint blockCount = 0;
     for (const sh::InterfaceBlock &block : interfaceBlocks)
     {
-        if (block.staticUse || block.layout != sh::BLOCKLAYOUT_PACKED)
+        if (block.active || block.layout != sh::BLOCKLAYOUT_PACKED)
         {
             blockCount += (block.arraySize ? block.arraySize : 1);
             if (blockCount > maxInterfaceBlocks)
             {
                 infoLog << errorMessage << maxInterfaceBlocks << ")";
                 return false;
             }
         }
@@ -272,56 +272,37 @@ void GetInterfaceBlockName(const GLuint 
         CopyStringToBuffer(name, blockName, bufSize, length);
     }
 }
 
 void InitUniformBlockLinker(const gl::Context *context,
                             const ProgramState &state,
                             UniformBlockLinker *blockLinker)
 {
-    if (state.getAttachedVertexShader())
-    {
-        blockLinker->addShaderBlocks(GL_VERTEX_SHADER,
-                                     &state.getAttachedVertexShader()->getUniformBlocks(context));
-    }
-
-    if (state.getAttachedFragmentShader())
+    for (ShaderType shaderType : AllShaderTypes())
     {
-        blockLinker->addShaderBlocks(GL_FRAGMENT_SHADER,
-                                     &state.getAttachedFragmentShader()->getUniformBlocks(context));
-    }
-
-    if (state.getAttachedComputeShader())
-    {
-        blockLinker->addShaderBlocks(GL_COMPUTE_SHADER,
-                                     &state.getAttachedComputeShader()->getUniformBlocks(context));
+        Shader *shader = state.getAttachedShader(shaderType);
+        if (shader)
+        {
+            blockLinker->addShaderBlocks(shaderType, &shader->getUniformBlocks(context));
+        }
     }
 }
 
 void InitShaderStorageBlockLinker(const gl::Context *context,
                                   const ProgramState &state,
                                   ShaderStorageBlockLinker *blockLinker)
 {
-    if (state.getAttachedVertexShader())
-    {
-        blockLinker->addShaderBlocks(
-            GL_VERTEX_SHADER, &state.getAttachedVertexShader()->getShaderStorageBlocks(context));
-    }
-
-    if (state.getAttachedFragmentShader())
+    for (ShaderType shaderType : AllShaderTypes())
     {
-        blockLinker->addShaderBlocks(
-            GL_FRAGMENT_SHADER,
-            &state.getAttachedFragmentShader()->getShaderStorageBlocks(context));
-    }
-
-    if (state.getAttachedComputeShader())
-    {
-        blockLinker->addShaderBlocks(
-            GL_COMPUTE_SHADER, &state.getAttachedComputeShader()->getShaderStorageBlocks(context));
+        Shader *shader = state.getAttachedShader(shaderType);
+        if (shader != nullptr)
+        {
+            blockLinker->addShaderBlocks(shaderType, &shader->getShaderStorageBlocks(context));
+        }
     }
 }
 
 // Find the matching varying or field by name.
 const sh::ShaderVariable *FindVaryingOrField(const ProgramMergedVaryings &varyings,
                                              const std::string &name)
 {
     const sh::ShaderVariable *var = nullptr;
@@ -391,16 +372,152 @@ const char *GetLinkMismatchErrorString(L
         case LinkMismatchError::MATRIX_PACKING_MISMATCH:
             return "Matrix Packing";
         default:
             UNREACHABLE();
             return "";
     }
 }
 
+LinkMismatchError LinkValidateInterfaceBlockFields(const sh::InterfaceBlockField &blockField1,
+                                                   const sh::InterfaceBlockField &blockField2,
+                                                   bool webglCompatibility,
+                                                   std::string *mismatchedBlockFieldName)
+{
+    if (blockField1.name != blockField2.name)
+    {
+        return LinkMismatchError::FIELD_NAME_MISMATCH;
+    }
+
+    // If webgl, validate precision of UBO fields, otherwise don't.  See Khronos bug 10287.
+    LinkMismatchError linkError = Program::LinkValidateVariablesBase(
+        blockField1, blockField2, webglCompatibility, true, mismatchedBlockFieldName);
+    if (linkError != LinkMismatchError::NO_MISMATCH)
+    {
+        AddParentPrefix(blockField1.name, mismatchedBlockFieldName);
+        return linkError;
+    }
+
+    if (blockField1.isRowMajorLayout != blockField2.isRowMajorLayout)
+    {
+        AddParentPrefix(blockField1.name, mismatchedBlockFieldName);
+        return LinkMismatchError::MATRIX_PACKING_MISMATCH;
+    }
+
+    return LinkMismatchError::NO_MISMATCH;
+}
+
+LinkMismatchError AreMatchingInterfaceBlocks(const sh::InterfaceBlock &interfaceBlock1,
+                                             const sh::InterfaceBlock &interfaceBlock2,
+                                             bool webglCompatibility,
+                                             std::string *mismatchedBlockFieldName)
+{
+    // validate blocks for the same member types
+    if (interfaceBlock1.fields.size() != interfaceBlock2.fields.size())
+    {
+        return LinkMismatchError::FIELD_NUMBER_MISMATCH;
+    }
+    if (interfaceBlock1.arraySize != interfaceBlock2.arraySize)
+    {
+        return LinkMismatchError::ARRAY_SIZE_MISMATCH;
+    }
+    if (interfaceBlock1.layout != interfaceBlock2.layout ||
+        interfaceBlock1.binding != interfaceBlock2.binding)
+    {
+        return LinkMismatchError::LAYOUT_QUALIFIER_MISMATCH;
+    }
+    const unsigned int numBlockMembers = static_cast<unsigned int>(interfaceBlock1.fields.size());
+    for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
+    {
+        const sh::InterfaceBlockField &member1 = interfaceBlock1.fields[blockMemberIndex];
+        const sh::InterfaceBlockField &member2 = interfaceBlock2.fields[blockMemberIndex];
+
+        LinkMismatchError linkError = LinkValidateInterfaceBlockFields(
+            member1, member2, webglCompatibility, mismatchedBlockFieldName);
+        if (linkError != LinkMismatchError::NO_MISMATCH)
+        {
+            return linkError;
+        }
+    }
+    return LinkMismatchError::NO_MISMATCH;
+}
+
+bool ValidateGraphicsInterfaceBlocks(const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks,
+                                     const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks,
+                                     InfoLog &infoLog,
+                                     bool webglCompatibility,
+                                     sh::BlockType blockType,
+                                     GLuint maxCombinedInterfaceBlocks)
+{
+    // Check that interface blocks defined in the vertex and fragment shaders are identical
+    typedef std::map<std::string, const sh::InterfaceBlock *> InterfaceBlockMap;
+    InterfaceBlockMap linkedInterfaceBlocks;
+    GLuint blockCount = 0;
+
+    for (const sh::InterfaceBlock &vertexInterfaceBlock : vertexInterfaceBlocks)
+    {
+        linkedInterfaceBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock;
+        if (IsActiveInterfaceBlock(vertexInterfaceBlock))
+        {
+            blockCount += std::max(vertexInterfaceBlock.arraySize, 1u);
+        }
+    }
+
+    for (const sh::InterfaceBlock &fragmentInterfaceBlock : fragmentInterfaceBlocks)
+    {
+        auto entry = linkedInterfaceBlocks.find(fragmentInterfaceBlock.name);
+        if (entry != linkedInterfaceBlocks.end())
+        {
+            const sh::InterfaceBlock &vertexInterfaceBlock = *(entry->second);
+            std::string mismatchedBlockFieldName;
+            LinkMismatchError linkError =
+                AreMatchingInterfaceBlocks(vertexInterfaceBlock, fragmentInterfaceBlock,
+                                           webglCompatibility, &mismatchedBlockFieldName);
+            if (linkError != LinkMismatchError::NO_MISMATCH)
+            {
+                LogLinkMismatch(infoLog, fragmentInterfaceBlock.name, "interface block", linkError,
+                                mismatchedBlockFieldName, ShaderType::Vertex, ShaderType::Fragment);
+                return false;
+            }
+        }
+
+        // [OpenGL ES 3.1] Chapter 7.6.2 Page 105:
+        // If a uniform block is used by multiple shader stages, each such use counts separately
+        // against this combined limit.
+        // [OpenGL ES 3.1] Chapter 7.8 Page 111:
+        // If a shader storage block in a program is referenced by multiple shaders, each such
+        // reference counts separately against this combined limit.
+        if (IsActiveInterfaceBlock(fragmentInterfaceBlock))
+        {
+            blockCount += std::max(fragmentInterfaceBlock.arraySize, 1u);
+        }
+    }
+
+    if (blockCount > maxCombinedInterfaceBlocks)
+    {
+        switch (blockType)
+        {
+            case sh::BlockType::BLOCK_UNIFORM:
+                infoLog << "The sum of the number of active uniform blocks exceeds "
+                           "MAX_COMBINED_UNIFORM_BLOCKS ("
+                        << maxCombinedInterfaceBlocks << ").";
+                break;
+            case sh::BlockType::BLOCK_BUFFER:
+                infoLog << "The sum of the number of active shader storage blocks exceeds "
+                           "MAX_COMBINED_SHADER_STORAGE_BLOCKS ("
+                        << maxCombinedInterfaceBlocks << ").";
+                break;
+            default:
+                UNREACHABLE();
+        }
+        return false;
+    }
+    return true;
+}
+
 }  // anonymous namespace
 
 const char *const g_fakepath = "C:\\fakepath";
 
 // InfoLog implementation.
 InfoLog::InfoLog()
 {
 }
@@ -484,47 +601,53 @@ bool InfoLog::empty() const
     return mLazyStream->rdbuf()->in_avail() == 0;
 }
 
 void LogLinkMismatch(InfoLog &infoLog,
                      const std::string &variableName,
                      const char *variableType,
                      LinkMismatchError linkError,
                      const std::string &mismatchedStructOrBlockFieldName,
-                     GLenum shaderType1,
-                     GLenum shaderType2)
+                     ShaderType shaderType1,
+                     ShaderType shaderType2)
 {
     std::ostringstream stream;
     stream << GetLinkMismatchErrorString(linkError) << "s of " << variableType << " '"
            << variableName;
 
     if (!mismatchedStructOrBlockFieldName.empty())
     {
         stream << "' member '" << variableName << "." << mismatchedStructOrBlockFieldName;
     }
 
     stream << "' differ between " << GetShaderTypeString(shaderType1) << " and "
            << GetShaderTypeString(shaderType2) << " shaders.";
 
     infoLog << stream.str();
 }
 
+bool IsActiveInterfaceBlock(const sh::InterfaceBlock &interfaceBlock)
+{
+    // Only 'packed' blocks are allowed to be considered inactive.
+    return interfaceBlock.active || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED;
+}
+
 // VariableLocation implementation.
 VariableLocation::VariableLocation() : arrayIndex(0), index(kUnused), ignored(false)
 {
 }
 
 VariableLocation::VariableLocation(unsigned int arrayIndex, unsigned int index)
     : arrayIndex(arrayIndex), index(index), ignored(false)
 {
     ASSERT(arrayIndex != GL_INVALID_INDEX);
 }
 
 // SamplerBindings implementation.
-SamplerBinding::SamplerBinding(GLenum textureTypeIn, size_t elementCount, bool unreferenced)
+SamplerBinding::SamplerBinding(TextureType textureTypeIn, size_t elementCount, bool unreferenced)
     : textureType(textureTypeIn), boundTextureUnits(elementCount, 0), unreferenced(unreferenced)
 {
 }
 
 SamplerBinding::SamplerBinding(const SamplerBinding &other) = default;
 
 SamplerBinding::~SamplerBinding() = default;
 
@@ -603,16 +726,34 @@ ProgramState::~ProgramState()
            !mAttachedGeometryShader);
 }
 
 const std::string &ProgramState::getLabel()
 {
     return mLabel;
 }
 
+Shader *ProgramState::getAttachedShader(ShaderType shaderType) const
+{
+    switch (shaderType)
+    {
+        case ShaderType::Vertex:
+            return mAttachedVertexShader;
+        case ShaderType::Fragment:
+            return mAttachedFragmentShader;
+        case ShaderType::Compute:
+            return mAttachedComputeShader;
+        case ShaderType::Geometry:
+            return mAttachedGeometryShader;
+        default:
+            UNREACHABLE();
+            return nullptr;
+    }
+}
+
 GLuint ProgramState::getUniformIndexFromName(const std::string &name) const
 {
     return GetResourceIndexFromName(mUniforms, name);
 }
 
 GLuint ProgramState::getBufferVariableIndexFromName(const std::string &name) const
 {
     return GetResourceIndexFromName(mBufferVariables, name);
@@ -699,17 +840,18 @@ void Program::onDestroy(const Context *c
     }
 
     if (mState.mAttachedGeometryShader != nullptr)
     {
         mState.mAttachedGeometryShader->release(context);
         mState.mAttachedGeometryShader = nullptr;
     }
 
-    mProgram->destroy(context);
+    // TODO(jmadill): Handle error in the Context.
+    ANGLE_SWALLOW_ERR(mProgram->destroy(context));
 
     ASSERT(!mState.mAttachedVertexShader && !mState.mAttachedFragmentShader &&
            !mState.mAttachedComputeShader && !mState.mAttachedGeometryShader);
     SafeDelete(mProgram);
 
     delete this;
 }
 
@@ -722,75 +864,75 @@ const std::string &Program::getLabel() c
 {
     return mState.mLabel;
 }
 
 void Program::attachShader(Shader *shader)
 {
     switch (shader->getType())
     {
-        case GL_VERTEX_SHADER:
+        case ShaderType::Vertex:
         {
             ASSERT(!mState.mAttachedVertexShader);
             mState.mAttachedVertexShader = shader;
             mState.mAttachedVertexShader->addRef();
             break;
         }
-        case GL_FRAGMENT_SHADER:
+        case ShaderType::Fragment:
         {
             ASSERT(!mState.mAttachedFragmentShader);
             mState.mAttachedFragmentShader = shader;
             mState.mAttachedFragmentShader->addRef();
             break;
         }
-        case GL_COMPUTE_SHADER:
+        case ShaderType::Compute:
         {
             ASSERT(!mState.mAttachedComputeShader);
             mState.mAttachedComputeShader = shader;
             mState.mAttachedComputeShader->addRef();
             break;
         }
-        case GL_GEOMETRY_SHADER_EXT:
+        case ShaderType::Geometry:
         {
             ASSERT(!mState.mAttachedGeometryShader);
             mState.mAttachedGeometryShader = shader;
             mState.mAttachedGeometryShader->addRef();
             break;
         }
         default:
             UNREACHABLE();
     }
 }
 
 void Program::detachShader(const Context *context, Shader *shader)
 {
     switch (shader->getType())
     {
-        case GL_VERTEX_SHADER:
+        case ShaderType::Vertex:
         {
             ASSERT(mState.mAttachedVertexShader == shader);
             shader->release(context);
             mState.mAttachedVertexShader = nullptr;
             break;
         }
-        case GL_FRAGMENT_SHADER:
+        case ShaderType::Fragment:
         {
             ASSERT(mState.mAttachedFragmentShader == shader);
             shader->release(context);
             mState.mAttachedFragmentShader = nullptr;
             break;
         }
-        case GL_COMPUTE_SHADER:
+        case ShaderType::Compute:
         {
             ASSERT(mState.mAttachedComputeShader == shader);
             shader->release(context);
             mState.mAttachedComputeShader = nullptr;
             break;
         }
-        case GL_GEOMETRY_SHADER_EXT:
+        case ShaderType::Geometry:
         {
             ASSERT(mState.mAttachedGeometryShader == shader);
             shader->release(context);
             mState.mAttachedGeometryShader = nullptr;
             break;
         }
         default:
             UNREACHABLE();
@@ -798,16 +940,21 @@ void Program::detachShader(const Context
 }
 
 int Program::getAttachedShadersCount() const
 {
     return (mState.mAttachedVertexShader ? 1 : 0) + (mState.mAttachedFragmentShader ? 1 : 0) +
            (mState.mAttachedComputeShader ? 1 : 0) + (mState.mAttachedGeometryShader ? 1 : 0);
 }
 
+const Shader *Program::getAttachedShader(ShaderType shaderType) const
+{
+    return mState.getAttachedShader(shaderType);
+}
+
 void Program::bindAttributeLocation(GLuint index, const char *name)
 {
     mAttributeBindings.bindLocation(index, name);
 }
 
 void Program::bindUniformLocation(GLuint index, const char *name)
 {
     mUniformLocationBindings.bindLocation(index, name);
@@ -819,17 +966,17 @@ void Program::bindFragmentInputLocation(
 }
 
 BindingInfo Program::getFragmentInputBindingInfo(const Context *context, GLint index) const
 {
     BindingInfo ret;
     ret.type  = GL_NONE;
     ret.valid = false;
 
-    Shader *fragmentShader = mState.getAttachedFragmentShader();
+    Shader *fragmentShader = mState.getAttachedShader(ShaderType::Fragment);
     ASSERT(fragmentShader);
 
     // Find the actual fragment shader varying we're interested in
     const std::vector<sh::Varying> &inputs = fragmentShader->getInputVaryings(context);
 
     for (const auto &binding : mFragmentInputBindings)
     {
         if (binding.second != static_cast<GLuint>(index))
@@ -897,41 +1044,45 @@ void Program::pathFragmentInputGen(const
 Error Program::link(const gl::Context *context)
 {
     const auto &data = context->getContextState();
 
     auto *platform   = ANGLEPlatformCurrent();
     double startTime = platform->currentTime(platform);
 
     unlink();
+    mInfoLog.reset();
+
+    // Validate we have properly attached shaders before checking the cache.
+    if (!linkValidateShaders(context, mInfoLog))
+    {
+        return NoError();
+    }
 
     ProgramHash programHash;
-    auto *cache = context->getMemoryProgramCache();
+    MemoryProgramCache *cache = context->getMemoryProgramCache();
     if (cache)
     {
         ANGLE_TRY_RESULT(cache->getProgram(context, this, &mState, &programHash), mLinked);
         ANGLE_HISTOGRAM_BOOLEAN("GPU.ANGLE.ProgramCache.LoadBinarySuccess", mLinked);
     }
 
     if (mLinked)
     {
         double delta = platform->currentTime(platform) - startTime;
         int us       = static_cast<int>(delta * 1000000.0);
         ANGLE_HISTOGRAM_COUNTS("GPU.ANGLE.ProgramCache.ProgramCacheHitTimeUS", us);
         return NoError();
     }
 
     // Cache load failed, fall through to normal linking.
     unlink();
-    mInfoLog.reset();
-
-    if (!linkValidateShaders(context, mInfoLog))
-    {
-        return NoError();
-    }
+
+    // Re-link shaders after the unlink call.
+    ASSERT(linkValidateShaders(context, mInfoLog));
 
     if (mState.mAttachedComputeShader)
     {
         if (!linkUniforms(context, mInfoLog, mUniformLocationBindings))
         {
             return NoError();
         }
 
@@ -1058,32 +1209,56 @@ Error Program::link(const gl::Context *c
 }
 
 void Program::updateLinkedShaderStages()
 {
     mState.mLinkedShaderStages.reset();
 
     if (mState.mAttachedVertexShader)
     {
-        mState.mLinkedShaderStages.set(SHADER_VERTEX);
+        mState.mLinkedShaderStages.set(ShaderType::Vertex);
     }
 
     if (mState.mAttachedFragmentShader)
     {
-        mState.mLinkedShaderStages.set(SHADER_FRAGMENT);
+        mState.mLinkedShaderStages.set(ShaderType::Fragment);
     }
 
     if (mState.mAttachedComputeShader)
     {
-        mState.mLinkedShaderStages.set(SHADER_COMPUTE);
+        mState.mLinkedShaderStages.set(ShaderType::Compute);
     }
 
     if (mState.mAttachedGeometryShader)
     {
-        mState.mLinkedShaderStages.set(SHADER_GEOMETRY);
+        mState.mLinkedShaderStages.set(ShaderType::Geometry);
+    }
+}
+
+void ProgramState::updateTransformFeedbackStrides()
+{
+    if (mTransformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS)
+    {
+        mTransformFeedbackStrides.resize(1);
+        size_t totalSize = 0;
+        for (auto &varying : mLinkedTransformFeedbackVaryings)
+        {
+            totalSize += varying.size() * VariableExternalSize(varying.type);
+        }
+        mTransformFeedbackStrides[0] = static_cast<GLsizei>(totalSize);
+    }
+    else
+    {
+        mTransformFeedbackStrides.resize(mLinkedTransformFeedbackVaryings.size());
+        for (size_t i = 0; i < mLinkedTransformFeedbackVaryings.size(); i++)
+        {
+            auto &varying = mLinkedTransformFeedbackVaryings[i];
+            mTransformFeedbackStrides[i] =
+                static_cast<GLsizei>(varying.size() * VariableExternalSize(varying.type));
+        }
     }
 }
 
 // Returns the program object to an unlinked state, before re-linking, or at destruction
 void Program::unlink()
 {
     mState.mAttributes.clear();
     mState.mAttributesTypeMask.reset();
@@ -1108,23 +1283,30 @@ void Program::unlink()
     mState.mGeometryShaderInputPrimitiveType  = GL_TRIANGLES;
     mState.mGeometryShaderOutputPrimitiveType = GL_TRIANGLE_STRIP;
     mState.mGeometryShaderInvocations         = 1;
     mState.mGeometryShaderMaxVertices         = 0;
 
     mValidated = false;
 
     mLinked = false;
+    mInfoLog.reset();
 }
 
 bool Program::isLinked() const
 {
     return mLinked;
 }
 
+bool Program::hasLinkedShaderStage(ShaderType shaderType) const
+{
+    ASSERT(shaderType != ShaderType::InvalidEnum);
+    return mState.mLinkedShaderStages[shaderType];
+}
+
 Error Program::loadBinary(const Context *context,
                           GLenum binaryFormat,
                           const void *binary,
                           GLsizei length)
 {
     unlink();
 
 #if ANGLE_PROGRAM_BINARY_LOAD != ANGLE_ENABLED
@@ -1832,49 +2014,50 @@ bool Program::validateSamplers(InfoLog *
     // Also skip the cache if the sample mapping has changed, or if we haven't ever validated.
     if (infoLog == nullptr && mCachedValidateSamplersResult.valid())
     {
         return mCachedValidateSamplersResult.value();
     }
 
     if (mTextureUnitTypesCache.empty())
     {
-        mTextureUnitTypesCache.resize(caps.maxCombinedTextureImageUnits, GL_NONE);
+        mTextureUnitTypesCache.resize(caps.maxCombinedTextureImageUnits, TextureType::InvalidEnum);
     }
     else
     {
-        std::fill(mTextureUnitTypesCache.begin(), mTextureUnitTypesCache.end(), GL_NONE);
+        std::fill(mTextureUnitTypesCache.begin(), mTextureUnitTypesCache.end(),
+                  TextureType::InvalidEnum);
     }
 
     // if any two active samplers in a program are of different types, but refer to the same
     // texture image unit, and this is the current program, then ValidateProgram will fail, and
     // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
     for (const auto &samplerBinding : mState.mSamplerBindings)
     {
         if (samplerBinding.unreferenced)
             continue;
 
-        GLenum textureType = samplerBinding.textureType;
+        TextureType textureType = samplerBinding.textureType;
 
         for (GLuint textureUnit : samplerBinding.boundTextureUnits)
         {
             if (textureUnit >= caps.maxCombinedTextureImageUnits)
             {
                 if (infoLog)
                 {
                     (*infoLog) << "Sampler uniform (" << textureUnit
                                << ") exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS ("
                                << caps.maxCombinedTextureImageUnits << ")";
                 }
 
                 mCachedValidateSamplersResult = false;
                 return false;
             }
 
-            if (mTextureUnitTypesCache[textureUnit] != GL_NONE)
+            if (mTextureUnitTypesCache[textureUnit] != TextureType::InvalidEnum)
             {
                 if (textureType != mTextureUnitTypesCache[textureUnit])
                 {
                     if (infoLog)
                     {
                         (*infoLog) << "Samplers of conflicting types refer to the same texture "
                                       "image unit ("
                                    << textureUnit << ").";
@@ -2097,17 +2280,17 @@ bool Program::linkValidateShaders(const 
 
     if (computeShader)
     {
         if (!computeShader->isCompiled(context))
         {
             infoLog << "Attached compute shader is not compiled.";
             return false;
         }
-        ASSERT(computeShader->getType() == GL_COMPUTE_SHADER);
+        ASSERT(computeShader->getType() == ShaderType::Compute);
 
         mState.mComputeShaderLocalSize = computeShader->getWorkGroupSize(context);
 
         // GLSL ES 3.10, 4.4.1.1 Compute Shader Inputs
         // If the work group size is not specified, a link time error should occur.
         if (!mState.mComputeShaderLocalSize.isDeclared())
         {
             infoLog << "Work group size is not specified.";
@@ -2116,24 +2299,24 @@ bool Program::linkValidateShaders(const 
     }
     else
     {
         if (!fragmentShader || !fragmentShader->isCompiled(context))
         {
             infoLog << "No compiled fragment shader when at least one graphics shader is attached.";
             return false;
         }
-        ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER);
+        ASSERT(fragmentShader->getType() == ShaderType::Fragment);
 
         if (!vertexShader || !vertexShader->isCompiled(context))
         {
             infoLog << "No compiled vertex shader when at least one graphics shader is attached.";
             return false;
         }
-        ASSERT(vertexShader->getType() == GL_VERTEX_SHADER);
+        ASSERT(vertexShader->getType() == ShaderType::Vertex);
 
         int vertexShaderVersion = vertexShader->getShaderVersion(context);
         if (fragmentShader->getShaderVersion(context) != vertexShaderVersion)
         {
             infoLog << "Fragment shader version does not match vertex shader version.";
             return false;
         }
 
@@ -2155,17 +2338,17 @@ bool Program::linkValidateShaders(const 
                 return false;
             }
 
             if (geometryShader->getShaderVersion(context) != vertexShaderVersion)
             {
                 mInfoLog << "Geometry shader version does not match vertex shader version.";
                 return false;
             }
-            ASSERT(geometryShader->getType() == GL_GEOMETRY_SHADER_EXT);
+            ASSERT(geometryShader->getType() == ShaderType::Geometry);
 
             Optional<GLenum> inputPrimitive =
                 geometryShader->getGeometryShaderInputPrimitiveType(context);
             if (!inputPrimitive.valid())
             {
                 mInfoLog << "Input primitive type is not specified in the geometry shader.";
                 return false;
             }
@@ -2256,17 +2439,17 @@ bool Program::linkValidateShaderInterfac
                                                   gl::InfoLog &infoLog) const
 {
     ASSERT(generatingShader->getShaderVersion(context) ==
            consumingShader->getShaderVersion(context));
 
     const std::vector<sh::Varying> &outputVaryings = generatingShader->getOutputVaryings(context);
     const std::vector<sh::Varying> &inputVaryings  = consumingShader->getInputVaryings(context);
 
-    bool validateGeometryShaderInputs = consumingShader->getType() == GL_GEOMETRY_SHADER_EXT;
+    bool validateGeometryShaderInputs = consumingShader->getType() == ShaderType::Geometry;
 
     for (const sh::Varying &input : inputVaryings)
     {
         bool matched = false;
 
         // Built-in varyings obey special rules
         if (input.isBuiltIn())
         {
@@ -2291,17 +2474,19 @@ bool Program::linkValidateShaderInterfac
                     return false;
                 }
 
                 matched = true;
                 break;
             }
         }
 
-        // We permit unmatched, unreferenced varyings
+        // We permit unmatched, unreferenced varyings. Note that this specifically depends on
+        // whether the input is statically used - a statically used input should fail this test even
+        // if it is not active. GLSL ES 3.00.6 section 4.3.10.
         if (!matched && input.staticUse)
         {
             infoLog << GetShaderTypeString(consumingShader->getType()) << " varying " << input.name
                     << " does not match any " << GetShaderTypeString(generatingShader->getType())
                     << " varying";
             return false;
         }
     }
@@ -2420,17 +2605,17 @@ void Program::linkSamplerAndImageBinding
     }
 
     mState.mSamplerUniformRange = RangeUI(low, high);
 
     // If uniform is a sampler type, insert it into the mSamplerBindings array.
     for (unsigned int samplerIndex : mState.mSamplerUniformRange)
     {
         const auto &samplerUniform = mState.mUniforms[samplerIndex];
-        GLenum textureType         = SamplerTypeToTextureType(samplerUniform.type);
+        TextureType textureType    = SamplerTypeToTextureType(samplerUniform.type);
         mState.mSamplerBindings.emplace_back(
             SamplerBinding(textureType, samplerUniform.getBasicTypeElementCount(), false));
     }
 }
 
 bool Program::linkAtomicCounterBuffers()
 {
     for (unsigned int index : mState.mAtomicCounterUniformRange)
@@ -2461,70 +2646,53 @@ bool Program::linkAtomicCounterBuffers()
             atomicCounterBuffer.binding = uniform.binding;
             atomicCounterBuffer.memberIndexes.push_back(index);
             atomicCounterBuffer.unionReferencesWith(uniform);
             mState.mAtomicCounterBuffers.push_back(atomicCounterBuffer);
             uniform.bufferIndex = static_cast<int>(mState.mAtomicCounterBuffers.size() - 1);
         }
     }
     // TODO(jie.a.chen@intel.com): Count each atomic counter buffer to validate against
-    // gl_Max[Vertex|Fragment|Compute|Combined]AtomicCounterBuffers.
+    // gl_Max[Vertex|Fragment|Compute|Geometry|Combined]AtomicCounterBuffers.
 
     return true;
 }
 
-LinkMismatchError Program::LinkValidateInterfaceBlockFields(
-    const sh::InterfaceBlockField &blockField1,
-    const sh::InterfaceBlockField &blockField2,
-    bool webglCompatibility,
-    std::string *mismatchedBlockFieldName)
-{
-    if (blockField1.name != blockField2.name)
-    {
-        return LinkMismatchError::FIELD_NAME_MISMATCH;
-    }
-
-    // If webgl, validate precision of UBO fields, otherwise don't.  See Khronos bug 10287.
-    LinkMismatchError linkError = LinkValidateVariablesBase(
-        blockField1, blockField2, webglCompatibility, true, mismatchedBlockFieldName);
-    if (linkError != LinkMismatchError::NO_MISMATCH)
-    {
-        AddParentPrefix(blockField1.name, mismatchedBlockFieldName);
-        return linkError;
-    }
-
-    if (blockField1.isRowMajorLayout != blockField2.isRowMajorLayout)
-    {
-        AddParentPrefix(blockField1.name, mismatchedBlockFieldName);
-        return LinkMismatchError::MATRIX_PACKING_MISMATCH;
-    }
-
-    return LinkMismatchError::NO_MISMATCH;
-}
-
 // Assigns locations to all attributes from the bindings and program locations.
 bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
 {
     const ContextState &data = context->getContextState();
-    auto *vertexShader       = mState.getAttachedVertexShader();
+    Shader *vertexShader     = mState.getAttachedShader(ShaderType::Vertex);
+
+    int shaderVersion = vertexShader->getShaderVersion(context);
 
     unsigned int usedLocations = 0;
-    mState.mAttributes         = vertexShader->getActiveAttributes(context);
+    if (shaderVersion >= 300)
+    {
+        // In GLSL ES 3.00.6, aliasing checks should be done with all declared attributes - see GLSL
+        // ES 3.00.6 section 12.46. Inactive attributes will be pruned after aliasing checks.
+        mState.mAttributes = vertexShader->getAllAttributes(context);
+    }
+    else
+    {
+        // In GLSL ES 1.00.17 we only do aliasing checks for active attributes.
+        mState.mAttributes = vertexShader->getActiveAttributes(context);
+    }
     GLuint maxAttribs          = data.getCaps().maxVertexAttributes;
 
     // TODO(jmadill): handle aliasing robustly
     if (mState.mAttributes.size() > maxAttribs)
     {
         infoLog << "Too many vertex attributes.";
         return false;
     }
 
     std::vector<sh::Attribute *> usedAttribMap(maxAttribs, nullptr);
 
-    // Link attributes that have a binding location
+    // Assign locations to attributes that have a binding location and check for attribute aliasing.
     for (sh::Attribute &attribute : mState.mAttributes)
     {
         // GLSL ES 3.10 January 2016 section 4.3.4: Vertex shader inputs can't be arrays or
         // structures, so we don't need to worry about adjusting their names or generating entries
         // for each member/element (unlike uniforms for example).
         ASSERT(!attribute.isArray() && !attribute.isStruct());
 
         int bindingLocation = mAttributeBindings.getBinding(attribute.name);
@@ -2535,73 +2703,93 @@ bool Program::linkAttributes(const Conte
 
         if (attribute.location != -1)
         {
             // Location is set by glBindAttribLocation or by location layout qualifier
             const int regs = VariableRegisterCount(attribute.type);
 
             if (static_cast<GLuint>(regs + attribute.location) > maxAttribs)
             {
-                infoLog << "Active attribute (" << attribute.name << ") at location "
-                        << attribute.location << " is too big to fit";
+                infoLog << "Attribute (" << attribute.name << ") at location " << attribute.location
+                        << " is too big to fit";
 
                 return false;
             }
 
             for (int reg = 0; reg < regs; reg++)
             {
                 const int regLocation               = attribute.location + reg;
                 sh::ShaderVariable *linkedAttribute = usedAttribMap[regLocation];
 
-                // In GLSL 3.00, attribute aliasing produces a link error
-                // In GLSL 1.00, attribute aliasing is allowed, but ANGLE currently has a bug
+                // In GLSL ES 3.00.6 and in WebGL, attribute aliasing produces a link error.
+                // In non-WebGL GLSL ES 1.00.17, attribute aliasing is allowed with some
+                // restrictions - see GLSL ES 1.00.17 section 2.10.4, but ANGLE currently has a bug.
                 if (linkedAttribute)
                 {
                     // TODO(jmadill): fix aliasing on ES2
-                    // if (mProgram->getShaderVersion() >= 300)
+                    // if (shaderVersion >= 300 && !webgl)
                     {
                         infoLog << "Attribute '" << attribute.name << "' aliases attribute '"
                                 << linkedAttribute->name << "' at location " << regLocation;
                         return false;
                     }
                 }
                 else
                 {
                     usedAttribMap[regLocation] = &attribute;
                 }
 
                 usedLocations |= 1 << regLocation;
             }
         }
     }
 
-    // Link attributes that don't have a binding location
+    // Assign locations to attributes that don't have a binding location.
     for (sh::Attribute &attribute : mState.mAttributes)
     {
         // Not set by glBindAttribLocation or by location layout qualifier
         if (attribute.location == -1)
         {
             int regs           = VariableRegisterCount(attribute.type);
             int availableIndex = AllocateFirstFreeBits(&usedLocations, regs, maxAttribs);
 
             if (availableIndex == -1 || static_cast<GLuint>(availableIndex + regs) > maxAttribs)
             {
-                infoLog << "Too many active attributes (" << attribute.name << ")";
+                infoLog << "Too many attributes (" << attribute.name << ")";
                 return false;
             }
 
             attribute.location = availableIndex;
         }
     }
 
     ASSERT(mState.mAttributesTypeMask.none());
     ASSERT(mState.mAttributesMask.none());
 
+    // Prune inactive attributes. This step is only needed on shaderVersion >= 300 since on earlier
+    // shader versions we're only processing active attributes to begin with.
+    if (shaderVersion >= 300)
+    {
+        for (auto attributeIter = mState.mAttributes.begin();
+             attributeIter != mState.mAttributes.end();)
+        {
+            if (attributeIter->active)
+            {
+                ++attributeIter;
+            }
+            else
+            {
+                attributeIter = mState.mAttributes.erase(attributeIter);
+            }
+        }
+    }
+
     for (const sh::Attribute &attribute : mState.mAttributes)
     {
+        ASSERT(attribute.active);
         ASSERT(attribute.location != -1);
         unsigned int regs = static_cast<unsigned int>(VariableRegisterCount(attribute.type));
 
         for (unsigned int r = 0; r < regs; r++)
         {
             unsigned int location = static_cast<unsigned int>(attribute.location) + r;
             mState.mActiveAttribLocationsMask.set(location);
             mState.mMaxActiveAttribLocation =
@@ -2615,213 +2803,136 @@ bool Program::linkAttributes(const Conte
                 mState.mAttributesMask.set(location);
             }
         }
     }
 
     return true;
 }
 
-bool Program::ValidateGraphicsInterfaceBlocks(
-    const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks,
-    const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks,
-    InfoLog &infoLog,
-    bool webglCompatibility,
-    sh::BlockType blockType,
-    GLuint maxCombinedInterfaceBlocks)
-{
-    // Check that interface blocks defined in the vertex and fragment shaders are identical
-    typedef std::map<std::string, const sh::InterfaceBlock *> InterfaceBlockMap;
-    InterfaceBlockMap linkedInterfaceBlocks;
-    GLuint blockCount = 0;
-
-    for (const sh::InterfaceBlock &vertexInterfaceBlock : vertexInterfaceBlocks)
-    {
-        linkedInterfaceBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock;
-        if (vertexInterfaceBlock.staticUse || vertexInterfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
-        {
-            blockCount += std::max(vertexInterfaceBlock.arraySize, 1u);
-        }
-    }
-
-    for (const sh::InterfaceBlock &fragmentInterfaceBlock : fragmentInterfaceBlocks)
-    {
-        auto entry = linkedInterfaceBlocks.find(fragmentInterfaceBlock.name);
-        if (entry != linkedInterfaceBlocks.end())
-        {
-            const sh::InterfaceBlock &vertexInterfaceBlock = *(entry->second);
-            std::string mismatchedBlockFieldName;
-            LinkMismatchError linkError =
-                AreMatchingInterfaceBlocks(vertexInterfaceBlock, fragmentInterfaceBlock,
-                                           webglCompatibility, &mismatchedBlockFieldName);
-            if (linkError != LinkMismatchError::NO_MISMATCH)
-            {
-                LogLinkMismatch(infoLog, fragmentInterfaceBlock.name, "interface block", linkError,
-                                mismatchedBlockFieldName, GL_VERTEX_SHADER, GL_FRAGMENT_SHADER);
-                return false;
-            }
-        }
-        else
-        {
-            if (fragmentInterfaceBlock.staticUse ||
-                fragmentInterfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
-            {
-                blockCount += std::max(fragmentInterfaceBlock.arraySize, 1u);
-            }
-        }
-    }
-
-    if (blockCount > maxCombinedInterfaceBlocks)
-    {
-        switch (blockType)
-        {
-            case sh::BlockType::BLOCK_UNIFORM:
-                infoLog << "The sum of the number of active uniform blocks exceeds "
-                           "MAX_COMBINED_UNIFORM_BLOCKS ("
-                        << maxCombinedInterfaceBlocks << ").";
-                break;
-            case sh::BlockType::BLOCK_BUFFER:
-                infoLog << "The sum of the number of active shader storage blocks exceeds "
-                           "MAX_COMBINED_SHADER_STORAGE_BLOCKS ("
-                        << maxCombinedInterfaceBlocks << ").";
-                break;
-            default:
-                UNREACHABLE();
-        }
-        return false;
-    }
-    return true;
-}
-
 bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog)
 {
     const auto &caps = context->getCaps();
 
     if (mState.mAttachedComputeShader)
     {
         Shader &computeShader              = *mState.mAttachedComputeShader;
         const auto &computeUniformBlocks   = computeShader.getUniformBlocks(context);
 
-        if (!validateInterfaceBlocksCount(
+        if (!ValidateInterfaceBlocksCount(
                 caps.maxComputeUniformBlocks, computeUniformBlocks,
                 "Compute shader uniform block count exceeds GL_MAX_COMPUTE_UNIFORM_BLOCKS (",
                 infoLog))
         {
             return false;
         }
 
         const auto &computeShaderStorageBlocks = computeShader.getShaderStorageBlocks(context);
-        if (!validateInterfaceBlocksCount(caps.maxComputeShaderStorageBlocks,
+        if (!ValidateInterfaceBlocksCount(caps.maxComputeShaderStorageBlocks,
                                           computeShaderStorageBlocks,
                                           "Compute shader shader storage block count exceeds "
                                           "GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS (",
                                           infoLog))
         {
             return false;
         }
         return true;
     }
 
     Shader &vertexShader   = *mState.mAttachedVertexShader;
     Shader &fragmentShader = *mState.mAttachedFragmentShader;
 
     const auto &vertexUniformBlocks   = vertexShader.getUniformBlocks(context);
     const auto &fragmentUniformBlocks = fragmentShader.getUniformBlocks(context);
 
-    if (!validateInterfaceBlocksCount(
+    if (!ValidateInterfaceBlocksCount(
             caps.maxVertexUniformBlocks, vertexUniformBlocks,
             "Vertex shader uniform block count exceeds GL_MAX_VERTEX_UNIFORM_BLOCKS (", infoLog))
     {
         return false;
     }
-    if (!validateInterfaceBlocksCount(
+    if (!ValidateInterfaceBlocksCount(
             caps.maxFragmentUniformBlocks, fragmentUniformBlocks,
             "Fragment shader uniform block count exceeds GL_MAX_FRAGMENT_UNIFORM_BLOCKS (",
             infoLog))
     {
 
         return false;
     }
 
+    Shader *geometryShader = mState.mAttachedGeometryShader;
+    if (geometryShader)
+    {
+        const auto &geometryUniformBlocks = geometryShader->getUniformBlocks(context);
+        if (!ValidateInterfaceBlocksCount(
+                caps.maxGeometryUniformBlocks, geometryUniformBlocks,
+                "Geometry shader uniform block count exceeds GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT (",
+                infoLog))
+        {
+            return false;
+        }
+    }
+
+    // TODO(jiawei.shao@intel.com): validate geometry shader uniform blocks.
     bool webglCompatibility = context->getExtensions().webglCompatibility;
     if (!ValidateGraphicsInterfaceBlocks(vertexUniformBlocks, fragmentUniformBlocks, infoLog,
                                          webglCompatibility, sh::BlockType::BLOCK_UNIFORM,
                                          caps.maxCombinedUniformBlocks))
     {
         return false;
     }
 
     if (context->getClientVersion() >= Version(3, 1))
     {
         const auto &vertexShaderStorageBlocks   = vertexShader.getShaderStorageBlocks(context);
         const auto &fragmentShaderStorageBlocks = fragmentShader.getShaderStorageBlocks(context);
 
-        if (!validateInterfaceBlocksCount(caps.maxVertexShaderStorageBlocks,
+        if (!ValidateInterfaceBlocksCount(caps.maxVertexShaderStorageBlocks,
                                           vertexShaderStorageBlocks,
                                           "Vertex shader shader storage block count exceeds "
                                           "GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS (",
                                           infoLog))
         {
             return false;
         }
-        if (!validateInterfaceBlocksCount(caps.maxFragmentShaderStorageBlocks,
+        if (!ValidateInterfaceBlocksCount(caps.maxFragmentShaderStorageBlocks,
                                           fragmentShaderStorageBlocks,
                                           "Fragment shader shader storage block count exceeds "
                                           "GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS (",
                                           infoLog))
         {
 
             return false;
         }
 
+        if (geometryShader)
+        {
+            const auto &geometryShaderStorageBlocks =
+                geometryShader->getShaderStorageBlocks(context);
+            if (!ValidateInterfaceBlocksCount(caps.maxGeometryShaderStorageBlocks,
+                                              geometryShaderStorageBlocks,
+                                              "Geometry shader shader storage block count exceeds "
+                                              "GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT (",
+                                              infoLog))
+            {
+                return false;
+            }
+        }
+
+        // TODO(jiawei.shao@intel.com): validate geometry shader shader storage blocks.
         if (!ValidateGraphicsInterfaceBlocks(
                 vertexShaderStorageBlocks, fragmentShaderStorageBlocks, infoLog, webglCompatibility,
                 sh::BlockType::BLOCK_BUFFER, caps.maxCombinedShaderStorageBlocks))
         {
             return false;
         }
     }
     return true;
 }
 
-LinkMismatchError Program::AreMatchingInterfaceBlocks(const sh::InterfaceBlock &interfaceBlock1,
-                                                      const sh::InterfaceBlock &interfaceBlock2,
-                                                      bool webglCompatibility,
-                                                      std::string *mismatchedBlockFieldName)
-{
-    // validate blocks for the same member types
-    if (interfaceBlock1.fields.size() != interfaceBlock2.fields.size())
-    {
-        return LinkMismatchError::FIELD_NUMBER_MISMATCH;
-    }
-    if (interfaceBlock1.arraySize != interfaceBlock2.arraySize)
-    {
-        return LinkMismatchError::ARRAY_SIZE_MISMATCH;
-    }
-    if (interfaceBlock1.layout != interfaceBlock2.layout ||
-        interfaceBlock1.binding != interfaceBlock2.binding)
-    {
-        return LinkMismatchError::LAYOUT_QUALIFIER_MISMATCH;
-    }
-    const unsigned int numBlockMembers = static_cast<unsigned int>(interfaceBlock1.fields.size());
-    for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
-    {
-        const sh::InterfaceBlockField &member1 = interfaceBlock1.fields[blockMemberIndex];
-        const sh::InterfaceBlockField &member2 = interfaceBlock2.fields[blockMemberIndex];
-
-        LinkMismatchError linkError = LinkValidateInterfaceBlockFields(
-            member1, member2, webglCompatibility, mismatchedBlockFieldName);
-        if (linkError != LinkMismatchError::NO_MISMATCH)
-        {
-            return linkError;
-        }
-    }
-    return LinkMismatchError::NO_MISMATCH;
-}
-
 LinkMismatchError Program::LinkValidateVariablesBase(const sh::ShaderVariable &variable1,
                                                      const sh::ShaderVariable &variable2,
                                                      bool validatePrecision,
                                                      bool validateArraySize,
                                                      std::string *mismatchedStructOrBlockMemberName)
 {
     if (variable1.type != variable2.type)
     {
@@ -3103,16 +3214,19 @@ bool Program::linkValidateTransformFeedb
 }
 
 bool Program::linkValidateGlobalNames(const Context *context, InfoLog &infoLog) const
 {
     const std::vector<sh::Uniform> &vertexUniforms =
         mState.mAttachedVertexShader->getUniforms(context);
     const std::vector<sh::Uniform> &fragmentUniforms =
         mState.mAttachedFragmentShader->getUniforms(context);
+    const std::vector<sh::Uniform> *geometryUniforms =
+        (mState.mAttachedGeometryShader) ? &mState.mAttachedGeometryShader->getUniforms(context)
+                                         : nullptr;
     const std::vector<sh::Attribute> &attributes =
         mState.mAttachedVertexShader->getActiveAttributes(context);
     for (const auto &attrib : attributes)
     {
         for (const auto &uniform : vertexUniforms)
         {
             if (uniform.name == attrib.name)
             {
@@ -3123,16 +3237,27 @@ bool Program::linkValidateGlobalNames(co
         for (const auto &uniform : fragmentUniforms)
         {
             if (uniform.name == attrib.name)
             {
                 infoLog << "Name conflicts between a uniform and an attribute: " << attrib.name;
                 return false;
             }
         }
+        if (geometryUniforms)
+        {
+            for (const auto &uniform : *geometryUniforms)
+            {
+                if (uniform.name == attrib.name)
+                {
+                    infoLog << "Name conflicts between a uniform and an attribute: " << attrib.name;
+                    return false;
+                }
+            }
+        }
     }
     return true;
 }
 
 void Program::gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyings)
 {
     // Gather the linked varyings that are used for transform feedback, they should all exist.
     mState.mLinkedTransformFeedbackVaryings.clear();
@@ -3160,16 +3285,17 @@ void Program::gatherTransformFeedbackVar
                 if (field != nullptr)
                 {
                     mState.mLinkedTransformFeedbackVaryings.emplace_back(*field, *varying);
                     break;
                 }
             }
         }
     }
+    mState.updateTransformFeedbackStrides();
 }
 
 ProgramMergedVaryings Program::getMergedVaryings(const Context *context) const
 {
     ProgramMergedVaryings merged;
 
     for (const sh::Varying &varying : mState.mAttachedVertexShader->getOutputVaryings(context))
     {
@@ -3423,17 +3549,17 @@ void Program::getUniformInternal(const C
 
 bool Program::samplesFromTexture(const gl::State &state, GLuint textureID) const
 {
     // Must be called after samplers are validated.
     ASSERT(mCachedValidateSamplersResult.valid() && mCachedValidateSamplersResult.value());
 
     for (const auto &binding : mState.mSamplerBindings)
     {
-        GLenum textureType = binding.textureType;
+        TextureType textureType = binding.textureType;
         for (const auto &unit : binding.boundTextureUnits)
         {
             GLenum programTextureID = state.getSamplerTextureId(unit, textureType);
             if (programTextureID == textureID)
             {
                 // TODO(jmadill): Check for appropriate overlap.
                 return true;
             }
--- a/gfx/angle/checkout/src/libANGLE/Program.h
+++ b/gfx/angle/checkout/src/libANGLE/Program.h
@@ -158,18 +158,20 @@ class InfoLog : angle::NonCopyable
     std::unique_ptr<std::stringstream> mLazyStream;
 };
 
 void LogLinkMismatch(InfoLog &infoLog,
                      const std::string &variableName,
                      const char *variableType,
                      LinkMismatchError linkError,
                      const std::string &mismatchedStructOrBlockFieldName,
-                     GLenum shaderType1,
-                     GLenum shaderType2);
+                     ShaderType shaderType1,
+                     ShaderType shaderType2);
+
+bool IsActiveInterfaceBlock(const sh::InterfaceBlock &interfaceBlock);
 
 // Struct used for correlating uniforms/elements of uniform arrays to handles
 struct VariableLocation
 {
     static constexpr unsigned int kUnused = GL_INVALID_INDEX;
 
     VariableLocation();
     VariableLocation(unsigned int arrayIndex, unsigned int index);
@@ -208,22 +210,22 @@ struct BindingInfo
 
     // True if the binding is valid, otherwise false.
     bool valid;
 };
 
 // This small structure encapsulates binding sampler uniforms to active GL textures.
 struct SamplerBinding
 {
-    SamplerBinding(GLenum textureTypeIn, size_t elementCount, bool unreferenced);
+    SamplerBinding(TextureType textureTypeIn, size_t elementCount, bool unreferenced);
     SamplerBinding(const SamplerBinding &other);
     ~SamplerBinding();
 
     // Necessary for retrieving active textures from the GL state.
-    GLenum textureType;
+    TextureType textureType;
 
     // List of all textures bound to this sampler, of type textureType.
     std::vector<GLuint> boundTextureUnits;
 
     // A note if this sampler is an unreferenced uniform.
     bool unreferenced;
 };
 
@@ -270,30 +272,25 @@ struct ImageBinding
     ImageBinding(size_t count);
     ImageBinding(GLuint imageUnit, size_t count);
     ImageBinding(const ImageBinding &other);
     ~ImageBinding();
 
     std::vector<GLuint> boundImageUnits;
 };
 
-using ShaderStagesMask = angle::BitSet<SHADER_TYPE_MAX>;
-
 class ProgramState final : angle::NonCopyable
 {
   public:
     ProgramState();
     ~ProgramState();
 
     const std::string &getLabel();
 
-    Shader *getAttachedVertexShader() const { return mAttachedVertexShader; }
-    Shader *getAttachedFragmentShader() const { return mAttachedFragmentShader; }
-    Shader *getAttachedComputeShader() const { return mAttachedComputeShader; }
-    Shader *getAttachedGeometryShader() const { return mAttachedGeometryShader; }
+    Shader *getAttachedShader(ShaderType shaderType) const;
     const std::vector<std::string> &getTransformFeedbackVaryingNames() const
     {
         return mTransformFeedbackVaryingNames;
     }
     GLint getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; }
     GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const
     {
         ASSERT(uniformBlockIndex < mUniformBlocks.size());
@@ -348,22 +345,24 @@ class ProgramState final : angle::NonCop
     GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const;
     GLuint getAttributeLocation(const std::string &name) const;
 
     GLuint getBufferVariableIndexFromName(const std::string &name) const;
 
     int getNumViews() const { return mNumViews; }
     bool usesMultiview() const { return mNumViews != -1; }
 
-    const ShaderStagesMask &getLinkedShaderStages() const { return mLinkedShaderStages; }
+    const ShaderBitSet &getLinkedShaderStages() const { return mLinkedShaderStages; }
 
   private:
     friend class MemoryProgramCache;
     friend class Program;
 
+    void updateTransformFeedbackStrides();
+
     std::string mLabel;
 
     sh::WorkGroupSize mComputeShaderLocalSize;
 
     Shader *mAttachedFragmentShader;
     Shader *mAttachedVertexShader;
     Shader *mAttachedComputeShader;
     Shader *mAttachedGeometryShader;
@@ -417,26 +416,29 @@ class ProgramState final : angle::NonCop
     DrawBufferMask mActiveOutputVariables;
 
     // Fragment output variable base types: FLOAT, INT, or UINT.  Ordered by location.
     std::vector<GLenum> mOutputVariableTypes;
     ComponentTypeMask mDrawBufferTypeMask;
 
     bool mBinaryRetrieveableHint;
     bool mSeparable;
-    ShaderStagesMask mLinkedShaderStages;
+    ShaderBitSet mLinkedShaderStages;
 
     // ANGLE_multiview.
     int mNumViews;
 
     // GL_EXT_geometry_shader.
     GLenum mGeometryShaderInputPrimitiveType;
     GLenum mGeometryShaderOutputPrimitiveType;
     int mGeometryShaderInvocations;
     int mGeometryShaderMaxVertices;
+
+    // The size of the data written to each transform feedback buffer per vertex.
+    std::vector<GLsizei> mTransformFeedbackStrides;
 };
 
 class ProgramBindings final : angle::NonCopyable
 {
   public:
     ProgramBindings();
     ~ProgramBindings();
 
@@ -473,40 +475,34 @@ class Program final : angle::NonCopyable
     const std::string &getLabel() const override;
 
     rx::ProgramImpl *getImplementation() const { return mProgram; }
 
     void attachShader(Shader *shader);
     void detachShader(const Context *context, Shader *shader);
     int getAttachedShadersCount() const;
 
-    const Shader *getAttachedVertexShader() const { return mState.mAttachedVertexShader; }
-    const Shader *getAttachedFragmentShader() const { return mState.mAttachedFragmentShader; }
-    const Shader *getAttachedComputeShader() const { return mState.mAttachedComputeShader; }
-    const Shader *getAttachedGeometryShader() const { return mState.mAttachedGeometryShader; }
+    const Shader *getAttachedShader(ShaderType shaderType) const;
 
     void bindAttributeLocation(GLuint index, const char *name);
     void bindUniformLocation(GLuint index, const char *name);
 
     // CHROMIUM_path_rendering
     BindingInfo getFragmentInputBindingInfo(const Context *context, GLint index) const;
     void bindFragmentInputLocation(GLint index, const char *name);
     void pathFragmentInputGen(const Context *context,
                               GLint index,
                               GLenum genMode,
                               GLint components,
                               const GLfloat *coeffs);
 
     Error link(const gl::Context *context);
     bool isLinked() const;
 
-    bool hasLinkedVertexShader() const { return mState.mLinkedShaderStages[SHADER_VERTEX]; }
-    bool hasLinkedFragmentShader() const { return mState.mLinkedShaderStages[SHADER_FRAGMENT]; }
-    bool hasLinkedComputeShader() const { return mState.mLinkedShaderStages[SHADER_COMPUTE]; }
-    bool hasLinkedGeometryShader() const { return mState.mLinkedShaderStages[SHADER_GEOMETRY]; }
+    bool hasLinkedShaderStage(ShaderType shaderType) const;
 
     Error loadBinary(const Context *context,
                      GLenum binaryFormat,
                      const void *binary,
                      GLsizei length);
     Error saveBinary(const Context *context,
                      GLenum *binaryFormat,
                      void *binary,
@@ -622,22 +618,16 @@ class Program final : angle::NonCopyable
     void setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode);
     void getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const;
     GLsizei getTransformFeedbackVaryingCount() const;
     GLsizei getTransformFeedbackVaryingMaxLength() const;
     GLenum getTransformFeedbackBufferMode() const;
     GLuint getTransformFeedbackVaryingResourceIndex(const GLchar *name) const;
     const TransformFeedbackVarying &getTransformFeedbackVaryingResource(GLuint index) const;
 
-    static LinkMismatchError LinkValidateInterfaceBlockFields(
-        const sh::InterfaceBlockField &blockField1,
-        const sh::InterfaceBlockField &blockField2,
-        bool webglCompatibility,
-        std::string *mismatchedBlockFieldName);
-
     void addRef();
     void release(const Context *context);
     unsigned int getRefCount() const;
     void flagForDeletion();
     bool isFlaggedForDeletion() const;
 
     void validate(const Caps &caps);
     bool validateSamplers(InfoLog *infoLog, const Caps &caps);
@@ -655,16 +645,27 @@ class Program final : angle::NonCopyable
     }
 
     const std::vector<ImageBinding> &getImageBindings() const { return mState.mImageBindings; }
     const sh::WorkGroupSize &getComputeShaderLocalSize() const
     {
         return mState.mComputeShaderLocalSize;
     }
 
+    GLenum getGeometryShaderInputPrimitiveType() const
+    {
+        return mState.mGeometryShaderInputPrimitiveType;
+    }
+    GLenum getGeometryShaderOutputPrimitiveType() const
+    {
+        return mState.mGeometryShaderOutputPrimitiveType;
+    }
+    GLint getGeometryShaderInvocations() const { return mState.mGeometryShaderInvocations; }
+    GLint getGeometryShaderMaxVertices() const { return mState.mGeometryShaderMaxVertices; }
+
     const ProgramState &getState() const { return mState; }
 
     static LinkMismatchError LinkValidateVariablesBase(
         const sh::ShaderVariable &variable1,
         const sh::ShaderVariable &variable2,
         bool validatePrecision,
         bool validateArraySize,
         std::string *mismatchedStructOrBlockMemberName);
@@ -687,46 +688,39 @@ class Program final : angle::NonCopyable
 
     int getNumViews() const { return mState.getNumViews(); }
     bool usesMultiview() const { return mState.usesMultiview(); }
 
     ComponentTypeMask getDrawBufferTypeMask() const { return mState.mDrawBufferTypeMask; }
     ComponentTypeMask getAttributesTypeMask() const { return mState.mAttributesTypeMask; }
     AttributesMask getAttributesMask() const { return mState.mAttributesMask; }
 
+    const std::vector<GLsizei> &getTransformFeedbackStrides() const
+    {
+        return mState.mTransformFeedbackStrides;
+    }
+
   private:
     ~Program() override;
 
     void unlink();
 
     bool linkValidateShaders(const Context *context, InfoLog &infoLog);
     bool linkAttributes(const Context *context, InfoLog &infoLog);
-    static bool ValidateGraphicsInterfaceBlocks(
-        const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks,
-        const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks,
-        InfoLog &infoLog,
-        bool webglCompatibility,
-        sh::BlockType blockType,
-        GLuint maxCombinedInterfaceBlocks);
     bool linkInterfaceBlocks(const Context *context, InfoLog &infoLog);
     bool linkVaryings(const Context *context, InfoLog &infoLog) const;
 
     bool linkUniforms(const Context *context,
                       InfoLog &infoLog,
                       const ProgramBindings &uniformLocationBindings);
     void linkSamplerAndImageBindings();
     bool linkAtomicCounterBuffers();
 
     void updateLinkedShaderStages();
 
-    static LinkMismatchError AreMatchingInterfaceBlocks(const sh::InterfaceBlock &interfaceBlock1,
-                                                        const sh::InterfaceBlock &interfaceBlock2,
-                                                        bool webglCompatibility,
-                                                        std::string *mismatchedBlockFieldName);
-
     static LinkMismatchError LinkValidateVaryings(const sh::Varying &outputVarying,
                                                   const sh::Varying &inputVarying,
                                                   int shaderVersion,
                                                   bool validateGeometryShaderInputVarying,
                                                   std::string *mismatchedStructFieldName);
 
     bool linkValidateShaderInterfaceMatching(const Context *context,
                                              Shader *generatingShader,
@@ -805,13 +799,13 @@ class Program final : angle::NonCopyable
 
     ShaderProgramManager *mResourceManager;
     const GLuint mHandle;
 
     InfoLog mInfoLog;
 
     // Cache for sampler validation
     Optional<bool> mCachedValidateSamplersResult;
-    std::vector<GLenum> mTextureUnitTypesCache;
+    std::vector<TextureType> mTextureUnitTypesCache;
 };
 }  // namespace gl
 
 #endif   // LIBANGLE_PROGRAM_H_
--- a/gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.cpp
+++ b/gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.cpp
@@ -44,117 +44,32 @@ int GetUniformLocationBinding(const Prog
         ASSERT(angle::EndsWith(uniform.name, "[0]"));
         std::string nameWithoutIndex = uniform.name.substr(0u, uniform.name.length() - 3u);
         return uniformLocationBindings.getBinding(nameWithoutIndex);
     }
     return binding;
 }
 
 template <typename VarT>
-void SetStaticUse(std::vector<VarT> *list,
-                  const std::string &name,
-                  GLenum shaderType,
-                  bool staticUse)
+void SetActive(std::vector<VarT> *list, const std::string &name, ShaderType shaderType, bool active)
 {
     for (auto &variable : *list)
     {
         if (variable.name == name)
         {
-            variable.setStaticUse(shaderType, staticUse);
+            variable.setActive(shaderType, active);
             return;
         }
     }
 }
 
-}  // anonymous namespace
-
-UniformLinker::UniformLinker(const ProgramState &state) : mState(state)
-{
-}
-
-UniformLinker::~UniformLinker() = default;
-
-void UniformLinker::getResults(std::vector<LinkedUniform> *uniforms,
-                               std::vector<VariableLocation> *uniformLocations)
-{
-    uniforms->swap(mUniforms);
-    uniformLocations->swap(mUniformLocations);
-}
-
-bool UniformLinker::link(const Context *context,
-                         InfoLog &infoLog,
-                         const ProgramBindings &uniformLocationBindings)
-{
-    if (mState.getAttachedVertexShader() && mState.getAttachedFragmentShader())
-    {
-        ASSERT(mState.getAttachedComputeShader() == nullptr);
-        if (!validateGraphicsUniforms(context, infoLog))
-        {
-            return false;
-        }
-    }
-
-    // Flatten the uniforms list (nested fields) into a simple list (no nesting).
-    // Also check the maximum uniform vector and sampler counts.
-    if (!flattenUniformsAndCheckCaps(context, infoLog))
-    {
-        return false;
-    }
-
-    if (!checkMaxCombinedAtomicCounters(context->getCaps(), infoLog))
-    {
-        return false;
-    }
-
-    if (!indexUniforms(infoLog, uniformLocationBindings))
-    {
-        return false;
-    }
-
-    return true;
-}
-
-bool UniformLinker::validateGraphicsUniforms(const Context *context, InfoLog &infoLog) const
-{
-    // Check that uniforms defined in the vertex and fragment shaders are identical
-    std::map<std::string, const sh::Uniform *> linkedUniforms;
-    const std::vector<sh::Uniform> &vertexUniforms =
-        mState.getAttachedVertexShader()->getUniforms(context);
-    const std::vector<sh::Uniform> &fragmentUniforms =
-        mState.getAttachedFragmentShader()->getUniforms(context);
-
-    for (const sh::Uniform &vertexUniform : vertexUniforms)
-    {
-        linkedUniforms[vertexUniform.name] = &vertexUniform;
-    }
-
-    for (const sh::Uniform &fragmentUniform : fragmentUniforms)
-    {
-        auto entry = linkedUniforms.find(fragmentUniform.name);
-        if (entry != linkedUniforms.end())
-        {
-            const sh::Uniform &vertexUniform = *(entry->second);
-            std::string mismatchedStructFieldName;
-            LinkMismatchError linkError =
-                LinkValidateUniforms(vertexUniform, fragmentUniform, &mismatchedStructFieldName);
-            if (linkError != LinkMismatchError::NO_MISMATCH)
-            {
-                LogLinkMismatch(infoLog, fragmentUniform.name, "uniform", linkError,
-                                mismatchedStructFieldName, GL_VERTEX_SHADER, GL_FRAGMENT_SHADER);
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
 // GLSL ES Spec 3.00.3, section 4.3.5.
-LinkMismatchError UniformLinker::LinkValidateUniforms(const sh::Uniform &uniform1,
-                                                      const sh::Uniform &uniform2,
-                                                      std::string *mismatchedStructFieldName)
+LinkMismatchError LinkValidateUniforms(const sh::Uniform &uniform1,
+                                       const sh::Uniform &uniform2,
+                                       std::string *mismatchedStructFieldName)
 {
 #if ANGLE_PROGRAM_LINK_VALIDATE_UNIFORM_PRECISION == ANGLE_ENABLED
     const bool validatePrecision = true;
 #else
     const bool validatePrecision = false;
 #endif
 
     LinkMismatchError linkError = Program::LinkValidateVariablesBase(
@@ -179,30 +94,143 @@ LinkMismatchError UniformLinker::LinkVal
     if (uniform1.offset != uniform2.offset)
     {
         return LinkMismatchError::OFFSET_MISMATCH;
     }
 
     return LinkMismatchError::NO_MISMATCH;
 }
 
+using ShaderUniform = std::pair<ShaderType, const sh::Uniform *>;
+
+bool ValidateGraphicsUniformsPerShader(const Context *context,
+                                       Shader *shaderToLink,
+                                       bool extendLinkedUniforms,
+                                       std::map<std::string, ShaderUniform> *linkedUniforms,
+                                       InfoLog &infoLog)
+{
+    ASSERT(context && shaderToLink && linkedUniforms);
+
+    for (const sh::Uniform &uniform : shaderToLink->getUniforms(context))
+    {
+        const auto &entry = linkedUniforms->find(uniform.name);
+        if (entry != linkedUniforms->end())
+        {
+            const sh::Uniform &linkedUniform = *(entry->second.second);
+            std::string mismatchedStructFieldName;
+            LinkMismatchError linkError =
+                LinkValidateUniforms(uniform, linkedUniform, &mismatchedStructFieldName);
+            if (linkError != LinkMismatchError::NO_MISMATCH)
+            {
+                LogLinkMismatch(infoLog, uniform.name, "uniform", linkError,
+                                mismatchedStructFieldName, entry->second.first,
+                                shaderToLink->getType());
+                return false;
+            }
+        }
+        else if (extendLinkedUniforms)
+        {
+            (*linkedUniforms)[uniform.name] = std::make_pair(shaderToLink->getType(), &uniform);
+        }
+    }
+
+    return true;
+}
+
+}  // anonymous namespace
+
+UniformLinker::UniformLinker(const ProgramState &state) : mState(state)
+{
+}
+
+UniformLinker::~UniformLinker() = default;
+
+void UniformLinker::getResults(std::vector<LinkedUniform> *uniforms,
+                               std::vector<VariableLocation> *uniformLocations)
+{
+    uniforms->swap(mUniforms);
+    uniformLocations->swap(mUniformLocations);
+}
+
+bool UniformLinker::link(const Context *context,
+                         InfoLog &infoLog,
+                         const ProgramBindings &uniformLocationBindings)
+{
+    if (mState.getAttachedShader(ShaderType::Vertex) &&
+        mState.getAttachedShader(ShaderType::Fragment))
+    {
+        ASSERT(mState.getAttachedShader(ShaderType::Compute) == nullptr);
+        if (!validateGraphicsUniforms(context, infoLog))
+        {
+            return false;
+        }
+    }
+
+    // Flatten the uniforms list (nested fields) into a simple list (no nesting).
+    // Also check the maximum uniform vector and sampler counts.
+    if (!flattenUniformsAndCheckCaps(context, infoLog))
+    {
+        return false;
+    }
+
+    if (!checkMaxCombinedAtomicCounters(context->getCaps(), infoLog))
+    {
+        return false;
+    }
+
+    if (!indexUniforms(infoLog, uniformLocationBindings))
+    {
+        return false;
+    }
+
+    return true;
+}
+
+bool UniformLinker::validateGraphicsUniforms(const Context *context, InfoLog &infoLog) const
+{
+    // Check that uniforms defined in the graphics shaders are identical
+    std::map<std::string, ShaderUniform> linkedUniforms;
+    for (const sh::Uniform &vertexUniform :
+         mState.getAttachedShader(ShaderType::Vertex)->getUniforms(context))
+    {
+        linkedUniforms[vertexUniform.name] = std::make_pair(ShaderType::Vertex, &vertexUniform);
+    }
+
+    std::vector<Shader *> activeShadersToLink;
+    if (mState.getAttachedShader(ShaderType::Geometry))
+    {
+        activeShadersToLink.push_back(mState.getAttachedShader(ShaderType::Geometry));
+    }
+    activeShadersToLink.push_back(mState.getAttachedShader(ShaderType::Fragment));
+
+    const size_t numActiveShadersToLink = activeShadersToLink.size();
+    for (size_t shaderIndex = 0; shaderIndex < numActiveShadersToLink; ++shaderIndex)
+    {
+        bool isLastShader = (shaderIndex == numActiveShadersToLink - 1);
+        if (!ValidateGraphicsUniformsPerShader(context, activeShadersToLink[shaderIndex],
+                                               !isLastShader, &linkedUniforms, infoLog))
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
 bool UniformLinker::indexUniforms(InfoLog &infoLog, const ProgramBindings &uniformLocationBindings)
 {
-    // All the locations where another uniform can't be located.
-    std::set<GLuint> reservedLocations;
     // Locations which have been allocated for an unused uniform.
     std::set<GLuint> ignoredLocations;
 
     int maxUniformLocation = -1;
 
     // Gather uniform locations that have been set either using the bindUniformLocation API or by
     // using a location layout qualifier and check conflicts between them.
     if (!gatherUniformLocationsAndCheckConflicts(infoLog, uniformLocationBindings,
-                                                 &reservedLocations, &ignoredLocations,
-                                                 &maxUniformLocation))
+                                                 &ignoredLocations, &maxUniformLocation))
     {
         return false;
     }
 
     // Conflicts have been checked, now we can prune non-statically used uniforms. Code further down
     // the line relies on only having statically used uniforms in mUniforms.
     pruneUnusedUniforms();
 
@@ -277,20 +305,22 @@ bool UniformLinker::indexUniforms(InfoLo
     }
 
     return true;
 }
 
 bool UniformLinker::gatherUniformLocationsAndCheckConflicts(
     InfoLog &infoLog,
     const ProgramBindings &uniformLocationBindings,
-    std::set<GLuint> *reservedLocations,
     std::set<GLuint> *ignoredLocations,
     int *maxUniformLocation)
 {
+    // All the locations where another uniform can't be located.
+    std::set<GLuint> reservedLocations;
+
     for (const LinkedUniform &uniform : mUniforms)
     {
         if (uniform.isBuiltIn())
         {
             continue;
         }
 
         int apiBoundLocation = GetUniformLocationBinding(uniformLocationBindings, uniform);
@@ -300,62 +330,66 @@ bool UniformLinker::gatherUniformLocatio
         {
             unsigned int elementCount = uniform.getBasicTypeElementCount();
 
             for (unsigned int arrayIndex = 0; arrayIndex < elementCount; arrayIndex++)
             {
                 // GLSL ES 3.10 section 4.4.3
                 int elementLocation = shaderLocation + arrayIndex;
                 *maxUniformLocation = std::max(*maxUniformLocation, elementLocation);
-                if (reservedLocations->find(elementLocation) != reservedLocations->end())
+                if (reservedLocations.find(elementLocation) != reservedLocations.end())
                 {
                     infoLog << "Multiple uniforms bound to location " << elementLocation << ".";
                     return false;
                 }
-                reservedLocations->insert(elementLocation);
-                if (!uniform.staticUse)
+                reservedLocations.insert(elementLocation);
+                if (!uniform.active)
                 {
                     ignoredLocations->insert(elementLocation);
                 }
             }
         }
         else if (apiBoundLocation != -1 && uniform.staticUse)
         {
             // Only the first location is reserved even if the uniform is an array.
             *maxUniformLocation = std::max(*maxUniformLocation, apiBoundLocation);
-            if (reservedLocations->find(apiBoundLocation) != reservedLocations->end())
+            if (reservedLocations.find(apiBoundLocation) != reservedLocations.end())
             {
                 infoLog << "Multiple uniforms bound to location " << apiBoundLocation << ".";
                 return false;
             }
-            reservedLocations->insert(apiBoundLocation);
+            reservedLocations.insert(apiBoundLocation);
+            if (!uniform.active)
+            {
+                ignoredLocations->insert(apiBoundLocation);
+            }
         }
     }
 
     // Record the uniform locations that were bound using the API for uniforms that were not found
     // from the shader. Other uniforms should not be assigned to those locations.
     for (const auto &locationBinding : uniformLocationBindings)
     {
         GLuint location = locationBinding.second;
-        if (reservedLocations->find(location) == reservedLocations->end())
+        if (reservedLocations.find(location) == reservedLocations.end())
         {
             ignoredLocations->insert(location);
             *maxUniformLocation = std::max(*maxUniformLocation, static_cast<int>(location));
         }
     }
 
     return true;
 }
 
 void UniformLinker::pruneUnusedUniforms()
 {
     auto uniformIter = mUniforms.begin();
     while (uniformIter != mUniforms.end())
     {
-        if (uniformIter->staticUse)
+        if (uniformIter->active)
         {
             ++uniformIter;
         }
         else
         {
             uniformIter = mUniforms.erase(uniformIter);
         }
     }
@@ -414,19 +448,19 @@ bool UniformLinker::flattenUniformsAndCh
 bool UniformLinker::flattenUniformsAndCheckCaps(const Context *context, InfoLog &infoLog)
 {
     std::vector<LinkedUniform> samplerUniforms;
     std::vector<LinkedUniform> imageUniforms;
     std::vector<LinkedUniform> atomicCounterUniforms;
 
     const Caps &caps = context->getCaps();
 
-    if (mState.getAttachedComputeShader())
+    if (mState.getAttachedShader(ShaderType::Compute))
     {
-        Shader *computeShader = mState.getAttachedComputeShader();
+        Shader *computeShader = mState.getAttachedShader(ShaderType::Compute);
 
         // TODO (mradev): check whether we need finer-grained component counting
         if (!flattenUniformsAndCheckCapsForShader(
                 context, computeShader, caps.maxComputeUniformComponents / 4,
                 caps.maxComputeTextureImageUnits, caps.maxComputeImageUniforms,
                 caps.maxComputeAtomicCounters,
                 "Compute shader active uniforms exceed MAX_COMPUTE_UNIFORM_COMPONENTS (",
                 "Compute shader sampler count exceeds MAX_COMPUTE_TEXTURE_IMAGE_UNITS (",
@@ -434,80 +468,97 @@ bool UniformLinker::flattenUniformsAndCh
                 "Compute shader atomic counter count exceeds MAX_COMPUTE_ATOMIC_COUNTERS (",
                 samplerUniforms, imageUniforms, atomicCounterUniforms, infoLog))
         {
             return false;
         }
     }
     else
     {
-        Shader *vertexShader = mState.getAttachedVertexShader();
+        Shader *vertexShader = mState.getAttachedShader(ShaderType::Vertex);
 
         if (!flattenUniformsAndCheckCapsForShader(
                 context, vertexShader, caps.maxVertexUniformVectors,
                 caps.maxVertexTextureImageUnits, caps.maxVertexImageUniforms,
                 caps.maxVertexAtomicCounters,
                 "Vertex shader active uniforms exceed MAX_VERTEX_UNIFORM_VECTORS (",
                 "Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (",
                 "Vertex shader image count exceeds MAX_VERTEX_IMAGE_UNIFORMS (",
                 "Vertex shader atomic counter count exceeds MAX_VERTEX_ATOMIC_COUNTERS (",
                 samplerUniforms, imageUniforms, atomicCounterUniforms, infoLog))
         {
             return false;
         }
 
-        Shader *fragmentShader = mState.getAttachedFragmentShader();
+        Shader *fragmentShader = mState.getAttachedShader(ShaderType::Fragment);
 
         if (!flattenUniformsAndCheckCapsForShader(
                 context, fragmentShader, caps.maxFragmentUniformVectors, caps.maxTextureImageUnits,
                 caps.maxFragmentImageUniforms, caps.maxFragmentAtomicCounters,
                 "Fragment shader active uniforms exceed MAX_FRAGMENT_UNIFORM_VECTORS (",
                 "Fragment shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (",
                 "Fragment shader image count exceeds MAX_FRAGMENT_IMAGE_UNIFORMS (",
                 "Fragment shader atomic counter count exceeds MAX_FRAGMENT_ATOMIC_COUNTERS (",
                 samplerUniforms, imageUniforms, atomicCounterUniforms, infoLog))
         {
             return false;
         }
+
+        Shader *geometryShader = mState.getAttachedShader(ShaderType::Geometry);
+        // TODO (jiawei.shao@intel.com): check whether we need finer-grained component counting
+        if (geometryShader &&
+            !flattenUniformsAndCheckCapsForShader(
+                context, geometryShader, caps.maxGeometryUniformComponents / 4,
+                caps.maxGeometryTextureImageUnits, caps.maxGeometryImageUniforms,
+                caps.maxGeometryAtomicCounters,
+                "Geometry shader active uniforms exceed MAX_GEOMETRY_UNIFORM_VECTORS_EXT (",
+                "Geometry shader sampler count exceeds MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT (",
+                "Geometry shader image count exceeds MAX_GEOMETRY_IMAGE_UNIFORMS_EXT (",
+                "Geometry shader atomic counter count exceeds MAX_GEOMETRY_ATOMIC_COUNTERS_EXT (",
+                samplerUniforms, imageUniforms, atomicCounterUniforms, infoLog))
+        {
+            return false;
+        }
     }
 
     mUniforms.insert(mUniforms.end(), samplerUniforms.begin(), samplerUniforms.end());
     mUniforms.insert(mUniforms.end(), imageUniforms.begin(), imageUniforms.end());
     mUniforms.insert(mUniforms.end(), atomicCounterUniforms.begin(), atomicCounterUniforms.end());
     return true;
 }
 
 UniformLinker::ShaderUniformCount UniformLinker::flattenUniform(
     const sh::Uniform &uniform,
     std::vector<LinkedUniform> *samplerUniforms,
     std::vector<LinkedUniform> *imageUniforms,
     std::vector<LinkedUniform> *atomicCounterUniforms,
-    GLenum shaderType)
+    ShaderType shaderType)
 {
     int location = uniform.location;
     ShaderUniformCount shaderUniformCount =
         flattenUniformImpl(uniform, uniform.name, uniform.mappedName, samplerUniforms,
-                           imageUniforms, atomicCounterUniforms, shaderType, uniform.staticUse,
-                           uniform.binding, uniform.offset, &location);
-    if (uniform.staticUse)
+                           imageUniforms, atomicCounterUniforms, shaderType, uniform.active,
+                           uniform.staticUse, uniform.binding, uniform.offset, &location);
+    if (uniform.active)
     {
         return shaderUniformCount;
     }
     return ShaderUniformCount();
 }
 
 UniformLinker::ShaderUniformCount UniformLinker::flattenArrayOfStructsUniform(
     const sh::ShaderVariable &uniform,
     unsigned int arrayNestingIndex,
     const std::string &namePrefix,
     const std::string &mappedNamePrefix,
     std::vector<LinkedUniform> *samplerUniforms,
     std::vector<LinkedUniform> *imageUniforms,
     std::vector<LinkedUniform> *atomicCounterUniforms,
-    GLenum shaderType,
+    ShaderType shaderType,
+    bool markActive,
     bool markStaticUse,
     int binding,
     int offset,
     int *location)
 {
     // Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the
     // innermost.
     ShaderUniformCount shaderUniformCount;
@@ -515,126 +566,133 @@ UniformLinker::ShaderUniformCount Unifor
     for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement)
     {
         const std::string elementName       = namePrefix + ArrayString(arrayElement);
         const std::string elementMappedName = mappedNamePrefix + ArrayString(arrayElement);
         if (arrayNestingIndex + 1u < uniform.arraySizes.size())
         {
             shaderUniformCount += flattenArrayOfStructsUniform(
                 uniform, arrayNestingIndex + 1u, elementName, elementMappedName, samplerUniforms,
-                imageUniforms, atomicCounterUniforms, shaderType, markStaticUse, binding, offset,
-                location);
+                imageUniforms, atomicCounterUniforms, shaderType, markActive, markStaticUse,
+                binding, offset, location);
         }
         else
         {
             shaderUniformCount += flattenStructUniform(
                 uniform.fields, elementName, elementMappedName, samplerUniforms, imageUniforms,
-                atomicCounterUniforms, shaderType, markStaticUse, binding, offset, location);
+                atomicCounterUniforms, shaderType, markActive, markStaticUse, binding, offset,
+                location);
         }
     }
     return shaderUniformCount;
 }
 
 UniformLinker::ShaderUniformCount UniformLinker::flattenStructUniform(
     const std::vector<sh::ShaderVariable> &fields,
     const std::string &namePrefix,
     const std::string &mappedNamePrefix,
     std::vector<LinkedUniform> *samplerUniforms,
     std::vector<LinkedUniform> *imageUniforms,
     std::vector<LinkedUniform> *atomicCounterUniforms,
-    GLenum shaderType,
+    ShaderType shaderType,
+    bool markActive,
     bool markStaticUse,
     int binding,
     int offset,
     int *location)
 {
     ShaderUniformCount shaderUniformCount;
     for (const sh::ShaderVariable &field : fields)
     {
         const std::string &fieldName       = namePrefix + "." + field.name;
         const std::string &fieldMappedName = mappedNamePrefix + "." + field.mappedName;
 
-        shaderUniformCount +=
-            flattenUniformImpl(field, fieldName, fieldMappedName, samplerUniforms, imageUniforms,
-                               atomicCounterUniforms, shaderType, markStaticUse, -1, -1, location);
+        shaderUniformCount += flattenUniformImpl(field, fieldName, fieldMappedName, samplerUniforms,
+                                                 imageUniforms, atomicCounterUniforms, shaderType,
+                                                 markActive, markStaticUse, -1, -1, location);
     }
     return shaderUniformCount;
 }
 
 UniformLinker::ShaderUniformCount UniformLinker::flattenArrayUniform(
     const sh::ShaderVariable &uniform,
     const std::string &namePrefix,
     const std::string &mappedNamePrefix,
     std::vector<LinkedUniform> *samplerUniforms,
     std::vector<LinkedUniform> *imageUniforms,
     std::vector<LinkedUniform> *atomicCounterUniforms,
-    GLenum shaderType,
+    ShaderType shaderType,
+    bool markActive,
     bool markStaticUse,
     int binding,
     int offset,
     int *location)
 {
     ShaderUniformCount shaderUniformCount;
 
     ASSERT(uniform.isArray());
     for (unsigned int arrayElement = 0u; arrayElement < uniform.getOutermostArraySize();
          ++arrayElement)
     {
         sh::ShaderVariable uniformElement = uniform;
         uniformElement.indexIntoArray(arrayElement);
         const std::string elementName       = namePrefix + ArrayString(arrayElement);
         const std::string elementMappedName = mappedNamePrefix + ArrayString(arrayElement);
 
-        shaderUniformCount += flattenUniformImpl(
-            uniformElement, elementName, elementMappedName, samplerUniforms, imageUniforms,
-            atomicCounterUniforms, shaderType, markStaticUse, binding, offset, location);
+        shaderUniformCount +=
+            flattenUniformImpl(uniformElement, elementName, elementMappedName, samplerUniforms,
+                               imageUniforms, atomicCounterUniforms, shaderType, markActive,
+                               markStaticUse, binding, offset, location);
     }
     return shaderUniformCount;
 }
 
 UniformLinker::ShaderUniformCount UniformLinker::flattenUniformImpl(
     const sh::ShaderVariable &uniform,
     const std::string &fullName,
     const std::string &fullMappedName,
     std::vector<LinkedUniform> *samplerUniforms,
     std::vector<LinkedUniform> *imageUniforms,
     std::vector<LinkedUniform> *atomicCounterUniforms,
-    GLenum shaderType,
+    ShaderType shaderType,
+    bool markActive,
     bool markStaticUse,
     int binding,
     int offset,
     int *location)
 {
     ASSERT(location);
     ShaderUniformCount shaderUniformCount;
 
     if (uniform.isStruct())
     {
         if (uniform.isArray())
         {
-            shaderUniformCount += flattenArrayOfStructsUniform(
-                uniform, 0u, fullName, fullMappedName, samplerUniforms, imageUniforms,
-                atomicCounterUniforms, shaderType, markStaticUse, binding, offset, location);
+            shaderUniformCount +=
+                flattenArrayOfStructsUniform(uniform, 0u, fullName, fullMappedName, samplerUniforms,
+                                             imageUniforms, atomicCounterUniforms, shaderType,
+                                             markActive, markStaticUse, binding, offset, location);
         }
         else
         {
-            shaderUniformCount += flattenStructUniform(
-                uniform.fields, fullName, fullMappedName, samplerUniforms, imageUniforms,
-                atomicCounterUniforms, shaderType, markStaticUse, binding, offset, location);
+            shaderUniformCount +=
+                flattenStructUniform(uniform.fields, fullName, fullMappedName, samplerUniforms,
+                                     imageUniforms, atomicCounterUniforms, shaderType, markActive,
+                                     markStaticUse, binding, offset, location);
         }
         return shaderUniformCount;
     }
     if (uniform.isArrayOfArrays())
     {
         // GLES 3.1 November 2016 section 7.3.1 page 77:
         // "For an active variable declared as an array of an aggregate data type (structures or
         // arrays), a separate entry will be generated for each active array element"
         return flattenArrayUniform(uniform, fullName, fullMappedName, samplerUniforms,
-                                   imageUniforms, atomicCounterUniforms, shaderType, markStaticUse,
-                                   binding, offset, location);
+                                   imageUniforms, atomicCounterUniforms, shaderType, markActive,
+                                   markStaticUse, binding, offset, location);
     }
 
     // Not a struct
     bool isSampler                              = IsSamplerType(uniform.type);
     bool isImage                                = IsImageType(uniform.type);
     bool isAtomicCounter                        = IsAtomicCounterType(uniform.type);
     std::vector<gl::LinkedUniform> *uniformList = &mUniforms;
     if (isSampler)
@@ -671,34 +729,39 @@ UniformLinker::ShaderUniformCount Unifor
         if (offset != -1)
         {
             existingUniform->offset = offset;
         }
         if (*location != -1)
         {
             existingUniform->location = *location;
         }
+        if (markActive)
+        {
+            existingUniform->active = true;
+            existingUniform->setActive(shaderType, true);
+        }
         if (markStaticUse)
         {
             existingUniform->staticUse = true;
-            existingUniform->setStaticUse(shaderType, true);
         }
     }
     else
     {
         ASSERT(uniform.arraySizes.size() <= 1u);
         LinkedUniform linkedUniform(uniform.type, uniform.precision, fullNameWithArrayIndex,
                                     uniform.arraySizes, binding, offset, *location, -1,
                                     sh::BlockMemberInfo::getDefaultBlockInfo());
         linkedUniform.mappedName                    = fullMappedNameWithArrayIndex;
+        linkedUniform.active                        = markActive;
         linkedUniform.staticUse                     = markStaticUse;
         linkedUniform.flattenedOffsetInParentArrays = uniform.flattenedOffsetInParentArrays;
-        if (markStaticUse)
+        if (markActive)
         {
-            linkedUniform.setStaticUse(shaderType, true);
+            linkedUniform.setActive(shaderType, true);
         }
 
         uniformList->push_back(linkedUniform);
     }
 
     // Struct and array of arrays uniforms get flattened so we can use getBasicTypeElementCount().
     unsigned int elementCount = uniform.getBasicTypeElementCount();
 
@@ -718,17 +781,17 @@ UniformLinker::ShaderUniformCount Unifor
     return shaderUniformCount;
 }
 
 bool UniformLinker::checkMaxCombinedAtomicCounters(const Caps &caps, InfoLog &infoLog)
 {
     unsigned int atomicCounterCount = 0;
     for (const auto &uniform : mUniforms)
     {
-        if (IsAtomicCounterType(uniform.type) && uniform.staticUse)
+        if (IsAtomicCounterType(uniform.type) && uniform.active)
         {
             atomicCounterCount += uniform.getBasicTypeElementCount();
             if (atomicCounterCount > caps.maxCombinedAtomicCounters)
             {
                 infoLog << "atomic counter count exceeds MAX_COMBINED_ATOMIC_COUNTERS"
                         << caps.maxCombinedAtomicCounters << ").";
                 return false;
             }
@@ -742,48 +805,47 @@ InterfaceBlockLinker::InterfaceBlockLink
     : mBlocksOut(blocksOut)
 {
 }
 
 InterfaceBlockLinker::~InterfaceBlockLinker()
 {
 }
 
-void InterfaceBlockLinker::addShaderBlocks(GLenum shader,
+void InterfaceBlockLinker::addShaderBlocks(ShaderType shader,
                                            const std::vector<sh::InterfaceBlock> *blocks)
 {
     mShaderBlocks.push_back(std::make_pair(shader, blocks));
 }
 
 void InterfaceBlockLinker::linkBlocks(const GetBlockSize &getBlockSize,
                                       const GetBlockMemberInfo &getMemberInfo) const
 {
     ASSERT(mBlocksOut->empty());
 
     std::set<std::string> visitedList;
 
     for (const auto &shaderBlocks : mShaderBlocks)
     {
-        const GLenum shaderType = shaderBlocks.first;
+        const ShaderType shaderType = shaderBlocks.first;
 
         for (const auto &block : *shaderBlocks.second)
         {
-            // Only 'packed' blocks are allowed to be considered inactive.
-            if (!block.staticUse && block.layout == sh::BLOCKLAYOUT_PACKED)
+            if (!IsActiveInterfaceBlock(block))
                 continue;
 
             if (visitedList.count(block.name) > 0)
             {
-                if (block.staticUse)
+                if (block.active)
                 {
                     for (InterfaceBlock &priorBlock : *mBlocksOut)
                     {
                         if (block.name == priorBlock.name)
                         {
-                            priorBlock.setStaticUse(shaderType, true);
+                            priorBlock.setActive(shaderType, true);
                             // Update the block members static use.
                             defineBlockMembers(nullptr, block.fields, block.fieldPrefix(),
                                                block.fieldMappedPrefix(), -1,
                                                block.blockType == sh::BlockType::BLOCK_BUFFER, 1,
                                                shaderType);
                         }
                     }
                 }
@@ -801,17 +863,17 @@ template <typename VarT>
 void InterfaceBlockLinker::defineArrayOfStructsBlockMembers(const GetBlockMemberInfo &getMemberInfo,
                                                             const VarT &field,
                                                             unsigned int arrayNestingIndex,
                                                             const std::string &prefix,
                                                             const std::string &mappedPrefix,
                                                             int blockIndex,
                                                             bool singleEntryForTopLevelArray,
                                                             int topLevelArraySize,
-                                                            GLenum shaderType) const
+                                                            ShaderType shaderType) const
 {
     // Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the
     // innermost.
     unsigned int entryGenerationArraySize = field.getNestedArraySize(arrayNestingIndex);
     if (singleEntryForTopLevelArray)
     {
         entryGenerationArraySize = 1;
     }
@@ -836,17 +898,17 @@ void InterfaceBlockLinker::defineArrayOf
 template <typename VarT>
 void InterfaceBlockLinker::defineBlockMembers(const GetBlockMemberInfo &getMemberInfo,
                                               const std::vector<VarT> &fields,
                                               const std::string &prefix,
                                               const std::string &mappedPrefix,
                                               int blockIndex,
                                               bool singleEntryForTopLevelArray,
                                               int topLevelArraySize,
-                                              GLenum shaderType) const
+                                              ShaderType shaderType) const
 {
     for (const VarT &field : fields)
     {
         std::string fullName = (prefix.empty() ? field.name : prefix + "." + field.name);
         std::string fullMappedName =
             (mappedPrefix.empty() ? field.mappedName : mappedPrefix + "." + field.mappedName);
 
         defineBlockMember(getMemberInfo, field, fullName, fullMappedName, blockIndex,
@@ -857,17 +919,17 @@ void InterfaceBlockLinker::defineBlockMe
 template <typename VarT>
 void InterfaceBlockLinker::defineBlockMember(const GetBlockMemberInfo &getMemberInfo,
                                              const VarT &field,
                                              const std::string &fullName,
                                              const std::string &fullMappedName,
                                              int blockIndex,
                                              bool singleEntryForTopLevelArray,
                                              int topLevelArraySize,
-                                             GLenum shaderType) const
+                                             ShaderType shaderType) const
 {
     int nextArraySize = topLevelArraySize;
     if (((field.isArray() && field.isStruct()) || field.isArrayOfArrays()) &&
         singleEntryForTopLevelArray)
     {
         // In OpenGL ES 3.10 spec, session 7.3.1.1 '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.'
@@ -917,17 +979,17 @@ void InterfaceBlockLinker::defineBlockMe
     if (field.isArray())
     {
         fullNameWithArrayIndex += "[0]";
         fullMappedNameWithArrayIndex += "[0]";
     }
 
     if (blockIndex == -1)
     {
-        updateBlockMemberStaticUsedImpl(fullNameWithArrayIndex, shaderType, field.staticUse);
+        updateBlockMemberActiveImpl(fullNameWithArrayIndex, shaderType, field.active);
     }
     else
     {
         // If getBlockMemberInfo returns false, the variable is optimized out.
         sh::BlockMemberInfo memberInfo;
         if (!getMemberInfo(fullName, fullMappedName, &memberInfo))
         {
             return;
@@ -937,17 +999,17 @@ void InterfaceBlockLinker::defineBlockMe
         defineBlockMemberImpl(field, fullNameWithArrayIndex, fullMappedNameWithArrayIndex,
                               blockIndex, memberInfo, nextArraySize, shaderType);
     }
 }
 
 void InterfaceBlockLinker::defineInterfaceBlock(const GetBlockSize &getBlockSize,
                                                 const GetBlockMemberInfo &getMemberInfo,
                                                 const sh::InterfaceBlock &interfaceBlock,
-                                                GLenum shaderType) const
+                                                ShaderType shaderType) const
 {
     size_t blockSize = 0;
     std::vector<unsigned int> blockIndexes;
 
     int blockIndex = static_cast<int>(mBlocksOut->size());
     // Track the first and last block member index to determine the range of active block members in
     // the block.
     size_t firstBlockMemberIndex = getCurrentBlockMemberIndex();
@@ -982,17 +1044,17 @@ void InterfaceBlockLinker::defineInterfa
         // ESSL 3.10 section 4.4.4 page 58:
         // Any uniform or shader storage block declared without a binding qualifier is initially
         // assigned to block binding point zero.
         int blockBinding =
             (interfaceBlock.binding == -1 ? 0 : interfaceBlock.binding + arrayElement);
         InterfaceBlock block(interfaceBlock.name, interfaceBlock.mappedName,
                              interfaceBlock.isArray(), arrayElement, blockBinding);
         block.memberIndexes = blockIndexes;
-        block.setStaticUse(shaderType, interfaceBlock.staticUse);
+        block.setActive(shaderType, interfaceBlock.active);
 
         // Since all block elements in an array share the same active interface blocks, they
         // will all be active once any block member is used. So, since interfaceBlock.name[0]
         // was active, here we will add every block element in the array.
         block.dataSize = static_cast<unsigned int>(blockSize);
         mBlocksOut->push_back(block);
     }
 }
@@ -1009,38 +1071,38 @@ UniformBlockLinker::~UniformBlockLinker(
 }
 
 void UniformBlockLinker::defineBlockMemberImpl(const sh::ShaderVariable &field,
                                                const std::string &fullName,
                                                const std::string &fullMappedName,
                                                int blockIndex,
                                                const sh::BlockMemberInfo &memberInfo,
                                                int /*topLevelArraySize*/,
-                                               GLenum shaderType) const
+                                               ShaderType shaderType) const
 {
     LinkedUniform newUniform(field.type, field.precision, fullName, field.arraySizes, -1, -1, -1,
                              blockIndex, memberInfo);
     newUniform.mappedName = fullMappedName;
-    newUniform.setStaticUse(shaderType, field.staticUse);
+    newUniform.setActive(shaderType, field.active);
 
     // Since block uniforms have no location, we don't need to store them in the uniform locations
     // list.
     mUniformsOut->push_back(newUniform);
 }
 
 size_t UniformBlockLinker::getCurrentBlockMemberIndex() const
 {
     return mUniformsOut->size();
 }
 
-void UniformBlockLinker::updateBlockMemberStaticUsedImpl(const std::string &fullName,
-                                                         GLenum shaderType,
-                                                         bool staticUse) const
+void UniformBlockLinker::updateBlockMemberActiveImpl(const std::string &fullName,
+                                                     ShaderType shaderType,
+                                                     bool active) const
 {
-    SetStaticUse(mUniformsOut, fullName, shaderType, staticUse);
+    SetActive(mUniformsOut, fullName, shaderType, active);
 }
 
 // ShaderStorageBlockLinker implementation.
 ShaderStorageBlockLinker::ShaderStorageBlockLinker(std::vector<InterfaceBlock> *blocksOut,
                                                    std::vector<BufferVariable> *bufferVariablesOut)
     : InterfaceBlockLinker(blocksOut), mBufferVariablesOut(bufferVariablesOut)
 {
 }
@@ -1050,38 +1112,38 @@ ShaderStorageBlockLinker::~ShaderStorage
 }
 
 void ShaderStorageBlockLinker::defineBlockMemberImpl(const sh::ShaderVariable &field,
                                                      const std::string &fullName,
                                                      const std::string &fullMappedName,
                                                      int blockIndex,
                                                      const sh::BlockMemberInfo &memberInfo,
                                                      int topLevelArraySize,
-                                                     GLenum shaderType) const
+                                                     ShaderType shaderType) const
 {
     BufferVariable newBufferVariable(field.type, field.precision, fullName, field.arraySizes,
                                      blockIndex, memberInfo);
     newBufferVariable.mappedName = fullMappedName;
-    newBufferVariable.setStaticUse(shaderType, field.staticUse);
+    newBufferVariable.setActive(shaderType, field.active);
 
     newBufferVariable.topLevelArraySize = topLevelArraySize;
 
     mBufferVariablesOut->push_back(newBufferVariable);
 }
 
 size_t ShaderStorageBlockLinker::getCurrentBlockMemberIndex() const
 {
     return mBufferVariablesOut->size();
 }
 
-void ShaderStorageBlockLinker::updateBlockMemberStaticUsedImpl(const std::string &fullName,
-                                                               GLenum shaderType,
-                                                               bool staticUse) const
+void ShaderStorageBlockLinker::updateBlockMemberActiveImpl(const std::string &fullName,
+                                                           ShaderType shaderType,
+                                                           bool active) const
 {
-    SetStaticUse(mBufferVariablesOut, fullName, shaderType, staticUse);
+    SetActive(mBufferVariablesOut, fullName, shaderType, active);
 }
 
 // AtomicCounterBufferLinker implementation.
 AtomicCounterBufferLinker::AtomicCounterBufferLinker(
     std::vector<AtomicCounterBuffer> *atomicCounterBuffersOut)
     : mAtomicCounterBuffersOut(atomicCounterBuffersOut)
 {
 }
--- a/gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.h
+++ b/gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.h
@@ -8,16 +8,17 @@
 // uniform locations. Populates data structures related to uniforms so that they can be stored in
 // program state.
 
 #ifndef LIBANGLE_UNIFORMLINKER_H_
 #define LIBANGLE_UNIFORMLINKER_H_
 
 #include "angle_gl.h"
 #include "common/angleutils.h"
+#include "libANGLE/PackedGLEnums_autogen.h"
 #include "libANGLE/VaryingPacking.h"
 
 #include <functional>
 
 namespace sh
 {
 struct BlockMemberInfo;
 struct InterfaceBlock;
@@ -76,20 +77,16 @@ class UniformLinker final : angle::NonCo
         unsigned int vectorCount;
         unsigned int samplerCount;
         unsigned int imageCount;
         unsigned int atomicCounterCount;
     };
 
     bool validateGraphicsUniforms(const Context *context, InfoLog &infoLog) const;
 
-    static LinkMismatchError LinkValidateUniforms(const sh::Uniform &uniform1,
-                                                  const sh::Uniform &uniform2,
-                                                  std::string *mismatchedStructFieldName);
-
     bool flattenUniformsAndCheckCapsForShader(const Context *context,
                                               Shader *shader,
                                               GLuint maxUniformComponents,
                                               GLuint maxTextureImageUnits,
                                               GLuint maxImageUnits,
                                               GLuint maxAtomicCounters,
                                               const std::string &componentsErrorMessage,
                                               const std::string &samplerErrorMessage,
@@ -102,74 +99,78 @@ class UniformLinker final : angle::NonCo
 
     bool flattenUniformsAndCheckCaps(const Context *context, InfoLog &infoLog);
     bool checkMaxCombinedAtomicCounters(const Caps &caps, InfoLog &infoLog);
 
     ShaderUniformCount flattenUniform(const sh::Uniform &uniform,
                                       std::vector<LinkedUniform> *samplerUniforms,
                                       std::vector<LinkedUniform> *imageUniforms,
                                       std::vector<LinkedUniform> *atomicCounterUniforms,
-                                      GLenum shaderType);
+                                      ShaderType shaderType);
 
     ShaderUniformCount flattenArrayOfStructsUniform(
         const sh::ShaderVariable &uniform,
         unsigned int arrayNestingIndex,
         const std::string &namePrefix,
         const std::string &mappedNamePrefix,
         std::vector<LinkedUniform> *samplerUniforms,
         std::vector<LinkedUniform> *imageUniforms,
         std::vector<LinkedUniform> *atomicCounterUniforms,
-        GLenum shaderType,
+
+        ShaderType shaderType,
+        bool markActive,
         bool markStaticUse,
         int binding,
         int offset,
         int *location);
 
     ShaderUniformCount flattenStructUniform(const std::vector<sh::ShaderVariable> &fields,
                                             const std::string &namePrefix,
                                             const std::string &mappedNamePrefix,
                                             std::vector<LinkedUniform> *samplerUniforms,
                                             std::vector<LinkedUniform> *imageUniforms,
                                             std::vector<LinkedUniform> *atomicCounterUniforms,
-                                            GLenum shaderType,
+                                            ShaderType shaderType,
+                                            bool markActive,
                                             bool markStaticUse,
                                             int binding,
                                             int offset,
                                             int *location);
 
     ShaderUniformCount flattenArrayUniform(const sh::ShaderVariable &uniform,
                                            const std::string &fullName,
                                            const std::string &fullMappedName,
                                            std::vector<LinkedUniform> *samplerUniforms,
                                            std::vector<LinkedUniform> *imageUniforms,
                                            std::vector<LinkedUniform> *atomicCounterUniforms,
-                                           GLenum shaderType,
+                                           ShaderType shaderType,
+                                           bool markActive,
                                            bool markStaticUse,
                                            int binding,
                                            int offset,
                                            int *location);
 
-    // markStaticUse is given as a separate parameter because it is tracked here at struct
-    // granularity.
+    // markActive and markStaticUse are given as separate parameters because they are tracked here
+    // at struct granularity.
     ShaderUniformCount flattenUniformImpl(const sh::ShaderVariable &uniform,
                                           const std::string &fullName,
                                           const std::string &fullMappedName,
                                           std::vector<LinkedUniform> *samplerUniforms,
                                           std::vector<LinkedUniform> *imageUniforms,
                                           std::vector<LinkedUniform> *atomicCounterUniforms,
-                                          GLenum shaderType,
+                                          ShaderType shaderType,
+                                          bool markActive,
                                           bool markStaticUse,
                                           int binding,
                                           int offset,
                                           int *location);
 
     bool indexUniforms(InfoLog &infoLog, const ProgramBindings &uniformLocationBindings);
     bool gatherUniformLocationsAndCheckConflicts(InfoLog &infoLog,
                                                  const ProgramBindings &uniformLocationBindings,
-                                                 std::set<GLuint> *reservedLocations,
                                                  std::set<GLuint> *ignoredLocations,
                                                  int *maxUniformLocation);
     void pruneUnusedUniforms();
 
     const ProgramState &mState;
     std::vector<LinkedUniform> mUniforms;
     std::vector<VariableLocation> mUniformLocations;
 };
@@ -184,97 +185,97 @@ class InterfaceBlockLinker : angle::NonC
 
     using GetBlockSize = std::function<
         bool(const std::string &blockName, const std::string &blockMappedName, size_t *sizeOut)>;
     using GetBlockMemberInfo = std::function<
         bool(const std::string &name, const std::string &mappedName, sh::BlockMemberInfo *infoOut)>;
 
     // This is called once per shader stage. It stores a pointer to the block vector, so it's
     // important that this class does not persist longer than the duration of Program::link.
-    void addShaderBlocks(GLenum shader, const std::vector<sh::InterfaceBlock> *blocks);
+    void addShaderBlocks(ShaderType shader, const std::vector<sh::InterfaceBlock> *blocks);
 
     // This is called once during a link operation, after all shader blocks are added.
     void linkBlocks(const GetBlockSize &getBlockSize,
                     const GetBlockMemberInfo &getMemberInfo) const;
 
   protected:
     InterfaceBlockLinker(std::vector<InterfaceBlock> *blocksOut);
     void defineInterfaceBlock(const GetBlockSize &getBlockSize,
                               const GetBlockMemberInfo &getMemberInfo,
                               const sh::InterfaceBlock &interfaceBlock,
-                              GLenum shaderType) const;
+                              ShaderType shaderType) const;
 
     template <typename VarT>
     void defineBlockMembers(const GetBlockMemberInfo &getMemberInfo,
                             const std::vector<VarT> &fields,
                             const std::string &prefix,
                             const std::string &mappedPrefix,
                             int blockIndex,
                             bool singleEntryForTopLevelArray,
                             int topLevelArraySize,
-                            GLenum shaderType) const;
+                            ShaderType shaderType) const;
     template <typename VarT>
     void defineBlockMember(const GetBlockMemberInfo &getMemberInfo,
                            const VarT &field,
                            const std::string &fullName,
                            const std::string &fullMappedName,
                            int blockIndex,
                            bool singleEntryForTopLevelArray,
                            int topLevelArraySize,
-                           GLenum shaderType) const;
+                           ShaderType shaderType) const;
 
     virtual void defineBlockMemberImpl(const sh::ShaderVariable &field,
                                        const std::string &fullName,
                                        const std::string &fullMappedName,
                                        int blockIndex,
                                        const sh::BlockMemberInfo &memberInfo,
                                        int topLevelArraySize,
-                                       GLenum shaderType) const                 = 0;
+                                       ShaderType shaderType) const             = 0;
     virtual size_t getCurrentBlockMemberIndex() const                           = 0;
-    virtual void updateBlockMemberStaticUsedImpl(const std::string &fullName,
-                                                 GLenum shaderType,
-                                                 bool staticUse) const          = 0;
+    virtual void updateBlockMemberActiveImpl(const std::string &fullName,
+                                             ShaderType shaderType,
+                                             bool active) const                 = 0;
 
-    using ShaderBlocks = std::pair<GLenum, const std::vector<sh::InterfaceBlock> *>;
+    using ShaderBlocks = std::pair<ShaderType, const std::vector<sh::InterfaceBlock> *>;
     std::vector<ShaderBlocks> mShaderBlocks;
 
     std::vector<InterfaceBlock> *mBlocksOut;
 
   private:
     template <typename VarT>
     void defineArrayOfStructsBlockMembers(const GetBlockMemberInfo &getMemberInfo,
                                           const VarT &field,
                                           unsigned int arrayNestingIndex,
                                           const std::string &prefix,
                                           const std::string &mappedPrefix,
                                           int blockIndex,
                                           bool singleEntryForTopLevelArray,
                                           int topLevelArraySize,
-                                          GLenum shaderType) const;
+                                          ShaderType shaderType) const;
 };
 
 class UniformBlockLinker final : public InterfaceBlockLinker
 {
   public:
     UniformBlockLinker(std::vector<InterfaceBlock> *blocksOut,
                        std::vector<LinkedUniform> *uniformsOut);
     ~UniformBlockLinker() override;
 
   private:
     void defineBlockMemberImpl(const sh::ShaderVariable &field,
                                const std::string &fullName,
                                const std::string &fullMappedName,
                                int blockIndex,
                                const sh::BlockMemberInfo &memberInfo,
                                int topLevelArraySize,
-                               GLenum shaderType) const override;
+                               ShaderType shaderType) const override;
     size_t getCurrentBlockMemberIndex() const override;
-    void updateBlockMemberStaticUsedImpl(const std::string &fullName,
-                                         GLenum shaderType,
-                                         bool staticUse) const override;
+    void updateBlockMemberActiveImpl(const std::string &fullName,
+                                     ShaderType shaderType,
+                                     bool active) const override;
     std::vector<LinkedUniform> *mUniformsOut;
 };
 
 class ShaderStorageBlockLinker final : public InterfaceBlockLinker
 {
   public:
     ShaderStorageBlockLinker(std::vector<InterfaceBlock> *blocksOut,
                              std::vector<BufferVariable> *bufferVariablesOut);
@@ -282,21 +283,21 @@ class ShaderStorageBlockLinker final : p
 
   private:
     void defineBlockMemberImpl(const sh::ShaderVariable &field,
                                const std::string &fullName,
                                const std::string &fullMappedName,
                                int blockIndex,
                                const sh::BlockMemberInfo &memberInfo,
                                int topLevelArraySize,
-                               GLenum shaderType) const override;
+                               ShaderType shaderType) const override;
     size_t getCurrentBlockMemberIndex() const override;
-    void updateBlockMemberStaticUsedImpl(const std::string &fullName,
-                                         GLenum shaderType,
-                                         bool staticUse) const override;
+    void updateBlockMemberActiveImpl(const std::string &fullName,
+                                     ShaderType shaderType,
+                                     bool active) const override;
     std::vector<BufferVariable> *mBufferVariablesOut;
 };
 
 class AtomicCounterBufferLinker final : angle::NonCopyable
 {
   public:
     AtomicCounterBufferLinker(std::vector<AtomicCounterBuffer> *atomicCounterBuffersOut);
     ~AtomicCounterBufferLinker();
--- a/gfx/angle/checkout/src/libANGLE/RefCountObject.h
+++ b/gfx/angle/checkout/src/libANGLE/RefCountObject.h
@@ -119,19 +119,22 @@ class BindingPointer
         // Objects have to be released before the resource manager is destroyed, so they must be explicitly cleaned up.
         ASSERT(mObject == nullptr);
     }
 
     virtual void set(const Context *context, ObjectType *newObject)
     {
         // addRef first in case newObject == mObject and this is the last reference to it.
         if (newObject != nullptr) reinterpret_cast<const RefCountObjectNoID*>(newObject)->addRef();
-        if (mObject != nullptr)
-            reinterpret_cast<RefCountObjectNoID *>(mObject)->release(context);
+        // Store the old pointer in a temporary so we can set the pointer before calling release.
+        // Otherwise the object could still be referenced when its destructor is called.
+        ObjectType *oldObject = mObject;
         mObject = newObject;
+        if (oldObject != nullptr)
+            reinterpret_cast<RefCountObjectNoID *>(oldObject)->release(context);
     }
 
     ObjectType *get() const { return mObject; }
     ObjectType *operator->() const { return mObject; }
 
     GLuint id() const { return (mObject != nullptr) ? mObject->id() : 0; }
 
     bool operator==(const BindingPointer<ObjectType> &other) const
--- a/gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp
+++ b/gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp
@@ -104,48 +104,48 @@ Error Renderbuffer::setStorage(const Con
                                size_t width,
                                size_t height)
 {
     ANGLE_TRY(orphanImages(context));
     ANGLE_TRY(mImplementation->setStorage(context, internalformat, width, height));
 
     mState.update(static_cast<GLsizei>(width), static_cast<GLsizei>(height), Format(internalformat),
                   0, InitState::MayNeedInit);
-    onStateChange(context, angle::SubjectMessage::STATE_CHANGE);
+    onStorageChange(context);
 
     return NoError();
 }
 
 Error Renderbuffer::setStorageMultisample(const Context *context,
                                           size_t samples,
                                           GLenum internalformat,
                                           size_t width,
                                           size_t height)
 {
     ANGLE_TRY(orphanImages(context));
     ANGLE_TRY(
         mImplementation->setStorageMultisample(context, samples, internalformat, width, height));
 
     mState.update(static_cast<GLsizei>(width), static_cast<GLsizei>(height), Format(internalformat),
                   static_cast<GLsizei>(samples), InitState::MayNeedInit);
-    onStateChange(context, angle::SubjectMessage::STATE_CHANGE);
+    onStorageChange(context);
 
     return NoError();
 }
 
 Error Renderbuffer::setStorageEGLImageTarget(const Context *context, egl::Image *image)
 {
     ANGLE_TRY(orphanImages(context));
     ANGLE_TRY(mImplementation->setStorageEGLImageTarget(context, image));
 
     setTargetImage(context, image);
 
     mState.update(static_cast<GLsizei>(image->getWidth()), static_cast<GLsizei>(image->getHeight()),
                   Format(image->getFormat()), 0, image->sourceInitState());
-    onStateChange(context, angle::SubjectMessage::STATE_CHANGE);
+    onStorageChange(context);
 
     return NoError();
 }
 
 rx::RenderbufferImpl *Renderbuffer::getImplementation() const
 {
     ASSERT(mImplementation);
     return mImplementation.get();
--- a/gfx/angle/checkout/src/libANGLE/ResourceManager.cpp
+++ b/gfx/angle/checkout/src/libANGLE/ResourceManager.cpp
@@ -156,20 +156,19 @@ void ShaderProgramManager::reset(const C
     {
         deleteShader(context, mShaders.begin()->first);
     }
     mShaders.clear();
 }
 
 GLuint ShaderProgramManager::createShader(rx::GLImplFactory *factory,
                                           const gl::Limitations &rendererLimitations,
-                                          GLenum type)
+                                          ShaderType type)
 {
-    ASSERT(type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER || type == GL_COMPUTE_SHADER ||
-           type == GL_GEOMETRY_SHADER_EXT);
+    ASSERT(type != ShaderType::InvalidEnum);
     GLuint handle    = mHandleAllocator.allocate();
     mShaders.assign(handle, new Shader(this, factory, rendererLimitations, type, handle));
     return handle;
 }
 
 void ShaderProgramManager::deleteShader(const Context *context, GLuint shader)
 {
     deleteObject(context, &mShaders, shader);
@@ -218,19 +217,21 @@ void ShaderProgramManager::deleteObject(
     {
         object->flagForDeletion();
     }
 }
 
 // TextureManager Implementation.
 
 // static
-Texture *TextureManager::AllocateNewObject(rx::GLImplFactory *factory, GLuint handle, GLenum target)
+Texture *TextureManager::AllocateNewObject(rx::GLImplFactory *factory,
+                                           GLuint handle,
+                                           TextureType type)
 {
-    Texture *texture = new Texture(factory, handle, target);
+    Texture *texture = new Texture(factory, handle, type);
     texture->addRef();
     return texture;
 }
 
 // static
 void TextureManager::DeleteObject(const Context *context, Texture *texture)
 {
     texture->release(context);
--- a/gfx/angle/checkout/src/libANGLE/ResourceManager.h
+++ b/gfx/angle/checkout/src/libANGLE/ResourceManager.h
@@ -125,17 +125,17 @@ class BufferManager : public TypedResour
 
 class ShaderProgramManager : public ResourceManagerBase<HandleAllocator>
 {
   public:
     ShaderProgramManager();
 
     GLuint createShader(rx::GLImplFactory *factory,
                         const Limitations &rendererLimitations,
-                        GLenum type);
+                        ShaderType type);
     void deleteShader(const Context *context, GLuint shader);
     Shader *getShader(GLuint handle) const;
 
     GLuint createProgram(rx::GLImplFactory *factory);
     void deleteProgram(const Context *context, GLuint program);
     Program *getProgram(GLuint handle) const;
 
   protected:
@@ -154,22 +154,22 @@ class ShaderProgramManager : public Reso
 class TextureManager : public TypedResourceManager<Texture, HandleAllocator, TextureManager>
 {
   public:
     GLuint createTexture();
     Texture *getTexture(GLuint handle) const;
 
     void signalAllTexturesDirty(const Context *context) const;
 
-    Texture *checkTextureAllocation(rx::GLImplFactory *factory, GLuint handle, GLenum target)
+    Texture *checkTextureAllocation(rx::GLImplFactory *factory, GLuint handle, TextureType type)
     {
-        return checkObjectAllocation(factory, handle, target);
+        return checkObjectAllocation(factory, handle, type);
     }
 
-    static Texture *AllocateNewObject(rx::GLImplFactory *factory, GLuint handle, GLenum target);
+    static Texture *AllocateNewObject(rx::GLImplFactory *factory, GLuint handle, TextureType type);
     static void DeleteObject(const Context *context, Texture *texture);
 
     void enableHandleAllocatorLogging();
 
   protected:
     ~TextureManager() override {}
 };
 
--- a/gfx/angle/checkout/src/libANGLE/Shader.cpp
+++ b/gfx/angle/checkout/src/libANGLE/Shader.cpp
@@ -30,17 +30,17 @@ namespace
 template <typename VarT>
 std::vector<VarT> GetActiveShaderVariables(const std::vector<VarT> *variableList)
 {
     ASSERT(variableList);
     std::vector<VarT> result;
     for (size_t varIndex = 0; varIndex < variableList->size(); varIndex++)
     {
         const VarT &var = variableList->at(varIndex);
-        if (var.staticUse)
+        if (var.active)
         {
             result.push_back(var);
         }
     }
     return result;
 }
 
 template <typename VarT>
@@ -69,39 +69,39 @@ bool CompareShaderVar(const sh::ShaderVa
     if (y.type == GL_NONE)
     {
         return true;
     }
 
     return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type);
 }
 
-const char *GetShaderTypeString(GLenum type)
+const char *GetShaderTypeString(ShaderType type)
 {
     switch (type)
     {
-        case GL_VERTEX_SHADER:
+        case ShaderType::Vertex:
             return "VERTEX";
 
-        case GL_FRAGMENT_SHADER:
+        case ShaderType::Fragment:
             return "FRAGMENT";
 
-        case GL_COMPUTE_SHADER:
+        case ShaderType::Compute:
             return "COMPUTE";
 
-        case GL_GEOMETRY_SHADER_EXT:
+        case ShaderType::Geometry:
             return "GEOMETRY";
 
         default:
             UNREACHABLE();
             return "";
     }
 }
 
-ShaderState::ShaderState(GLenum shaderType)
+ShaderState::ShaderState(ShaderType shaderType)
     : mLabel(),
       mShaderType(shaderType),
       mShaderVersion(100),
       mNumViews(-1),
       mGeometryShaderInvocations(1),
       mCompileStatus(CompileStatus::NOT_COMPILED)
 {
     mLocalSize.fill(-1);
@@ -109,17 +109,17 @@ ShaderState::ShaderState(GLenum shaderTy
 
 ShaderState::~ShaderState()
 {
 }
 
 Shader::Shader(ShaderProgramManager *manager,
                rx::GLImplFactory *implFactory,
                const gl::Limitations &rendererLimitations,
-               GLenum type,
+               ShaderType type,
                GLuint handle)
     : mState(type),
       mImplementation(implFactory->createShader(mState)),
       mRendererLimitations(rendererLimitations),
       mHandle(handle),
       mType(type),
       mRefCount(0),
       mDeleteStatus(false),
@@ -389,41 +389,41 @@ void Shader::resolveCompile(const Contex
     mState.mShaderVersion = sh::GetShaderVersion(compilerHandle);
 
     mState.mUniforms        = GetShaderVariables(sh::GetUniforms(compilerHandle));
     mState.mUniformBlocks       = GetShaderVariables(sh::GetUniformBlocks(compilerHandle));
     mState.mShaderStorageBlocks = GetShaderVariables(sh::GetShaderStorageBlocks(compilerHandle));
 
     switch (mState.mShaderType)
     {
-        case GL_COMPUTE_SHADER:
+        case ShaderType::Compute:
         {
             mState.mLocalSize = sh::GetComputeShaderLocalGroupSize(compilerHandle);
             break;
         }
-        case GL_VERTEX_SHADER:
+        case ShaderType::Vertex:
         {
             {
                 mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
-                mState.mActiveAttributes =
-                    GetActiveShaderVariables(sh::GetAttributes(compilerHandle));
+                mState.mAllAttributes    = GetShaderVariables(sh::GetAttributes(compilerHandle));
+                mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes);
                 mState.mNumViews = sh::GetVertexShaderNumViews(compilerHandle);
             }
             break;
         }
-        case GL_FRAGMENT_SHADER:
+        case ShaderType::Fragment:
         {
             mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
             // TODO(jmadill): Figure out why we only sort in the FS, and if we need to.
             std::sort(mState.mInputVaryings.begin(), mState.mInputVaryings.end(), CompareShaderVar);
             mState.mActiveOutputVariables =
                 GetActiveShaderVariables(sh::GetOutputVariables(compilerHandle));
             break;
         }
-        case GL_GEOMETRY_SHADER_EXT:
+        case ShaderType::Geometry:
         {
             mState.mInputVaryings  = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
             mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
 
             if (sh::HasValidGeometryShaderInputPrimitiveType(compilerHandle))
             {
                 mState.mGeometryShaderInputPrimitiveType =
                     sh::GetGeometryShaderInputPrimitiveType(compilerHandle);
@@ -524,27 +524,33 @@ const std::vector<sh::InterfaceBlock> &S
 }
 
 const std::vector<sh::Attribute> &Shader::getActiveAttributes(const Context *context)
 {
     resolveCompile(context);
     return mState.getActiveAttributes();
 }
 
+const std::vector<sh::Attribute> &Shader::getAllAttributes(const Context *context)
+{
+    resolveCompile(context);
+    return mState.getAllAttributes();
+}
+
 const std::vector<sh::OutputVariable> &Shader::getActiveOutputVariables(const Context *context)
 {
     resolveCompile(context);
     return mState.getActiveOutputVariables();
 }
 
 std::string Shader::getTransformFeedbackVaryingMappedName(const std::string &tfVaryingName,
                                                           const Context *context)
 {
     // TODO(jiawei.shao@intel.com): support transform feedback on geometry shader.
-    ASSERT(mState.getShaderType() == GL_VERTEX_SHADER);
+    ASSERT(mState.getShaderType() == ShaderType::Vertex);
     const auto &varyings = getOutputVaryings(context);
     auto bracketPos      = tfVaryingName.find("[");
     if (bracketPos != std::string::npos)
     {
         auto tfVaryingBaseName = tfVaryingName.substr(0, bracketPos);
         for (const auto &varying : varyings)
         {
             if (varying.name == tfVaryingBaseName)
--- a/gfx/angle/checkout/src/libANGLE/Shader.h
+++ b/gfx/angle/checkout/src/libANGLE/Shader.h
@@ -46,60 +46,62 @@ enum class CompileStatus
     NOT_COMPILED,
     COMPILE_REQUESTED,
     COMPILED,
 };
 
 class ShaderState final : angle::NonCopyable
 {
   public:
-    ShaderState(GLenum shaderType);
+    ShaderState(ShaderType shaderType);
     ~ShaderState();
 
     const std::string &getLabel() const { return mLabel; }
 
     const std::string &getSource() const { return mSource; }
     const std::string &getTranslatedSource() const { return mTranslatedSource; }
 
-    GLenum getShaderType() const { return mShaderType; }
+    ShaderType getShaderType() const { return mShaderType; }
     int getShaderVersion() const { return mShaderVersion; }
 
     const std::vector<sh::Varying> &getInputVaryings() const { return mInputVaryings; }
     const std::vector<sh::Varying> &getOutputVaryings() const { return mOutputVaryings; }
     const std::vector<sh::Uniform> &getUniforms() const { return mUniforms; }
     const std::vector<sh::InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; }
     const std::vector<sh::InterfaceBlock> &getShaderStorageBlocks() const
     {
         return mShaderStorageBlocks;
     }
     const std::vector<sh::Attribute> &getActiveAttributes() const { return mActiveAttributes; }
+    const std::vector<sh::Attribute> &getAllAttributes() const { return mAllAttributes; }
     const std::vector<sh::OutputVariable> &getActiveOutputVariables() const
     {
         return mActiveOutputVariables;
     }
 
     bool compilePending() const { return mCompileStatus == CompileStatus::COMPILE_REQUESTED; }
 
   private:
     friend class Shader;
 
     std::string mLabel;
 
-    GLenum mShaderType;
+    ShaderType mShaderType;
     int mShaderVersion;
     std::string mTranslatedSource;
     std::string mSource;
 
     sh::WorkGroupSize mLocalSize;
 
     std::vector<sh::Varying> mInputVaryings;
     std::vector<sh::Varying> mOutputVaryings;
     std::vector<sh::Uniform> mUniforms;
     std::vector<sh::InterfaceBlock> mUniformBlocks;
     std::vector<sh::InterfaceBlock> mShaderStorageBlocks;
+    std::vector<sh::Attribute> mAllAttributes;
     std::vector<sh::Attribute> mActiveAttributes;
     std::vector<sh::OutputVariable> mActiveOutputVariables;
 
     // ANGLE_multiview.
     int mNumViews;
 
     // Geometry Shader.
     Optional<GLenum> mGeometryShaderInputPrimitiveType;
@@ -112,25 +114,25 @@ class ShaderState final : angle::NonCopy
 };
 
 class Shader final : angle::NonCopyable, public LabeledObject
 {
   public:
     Shader(ShaderProgramManager *manager,
            rx::GLImplFactory *implFactory,
            const gl::Limitations &rendererLimitations,
-           GLenum type,
+           ShaderType type,
            GLuint handle);
 
     void onDestroy(const Context *context);
 
     void setLabel(const std::string &label) override;
     const std::string &getLabel() const override;
 
-    GLenum getType() const { return mType; }
+    ShaderType getType() const { return mType; }
     GLuint getHandle() const;
 
     rx::ShaderImpl *getImplementation() const { return mImplementation.get(); }
 
     void setSource(GLsizei count, const char *const *string, const GLint *length);
     int getInfoLogLength(const Context *context);
     void getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog);
     int getSourceLength() const;
@@ -160,16 +162,17 @@ class Shader final : angle::NonCopyable,
     int getShaderVersion(const Context *context);
 
     const std::vector<sh::Varying> &getInputVaryings(const Context *context);
     const std::vector<sh::Varying> &getOutputVaryings(const Context *context);
     const std::vector<sh::Uniform> &getUniforms(const Context *context);
     const std::vector<sh::InterfaceBlock> &getUniformBlocks(const Context *context);
     const std::vector<sh::InterfaceBlock> &getShaderStorageBlocks(const Context *context);
     const std::vector<sh::Attribute> &getActiveAttributes(const Context *context);
+    const std::vector<sh::Attribute> &getAllAttributes(const Context *context);
     const std::vector<sh::OutputVariable> &getActiveOutputVariables(const Context *context);
 
     // Returns mapped name of a transform feedback varying. The original name may contain array
     // brackets with an index inside, which will get copied to the mapped name. The varying must be
     // known to be declared in the shader.
     std::string getTransformFeedbackVaryingMappedName(const std::string &tfVaryingName,
                                                       const Context *context);
 
@@ -195,25 +198,25 @@ class Shader final : angle::NonCopyable,
 
     ShaderState mState;
     std::string mLastCompiledSource;
     std::string mLastCompiledSourcePath;
     ShCompileOptions mLastCompileOptions;
     std::unique_ptr<rx::ShaderImpl> mImplementation;
     const gl::Limitations &mRendererLimitations;
     const GLuint mHandle;
-    const GLenum mType;
+    const ShaderType mType;
     unsigned int mRefCount;     // Number of program objects this shader is attached to
     bool mDeleteStatus;         // Flag to indicate that the shader can be deleted when no longer in use
     std::string mInfoLog;
 
     // We keep a reference to the translator in order to defer compiles while preserving settings.
     BindingPointer<Compiler> mBoundCompiler;
 
     ShaderProgramManager *mResourceManager;
 };
 
 bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y);
 
-const char *GetShaderTypeString(GLenum type);
+const char *GetShaderTypeString(ShaderType type);
 }  // namespace gl
 
 #endif   // LIBANGLE_SHADER_H_
--- a/gfx/angle/checkout/src/libANGLE/State.cpp
+++ b/gfx/angle/checkout/src/libANGLE/State.cpp
@@ -3,18 +3,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 // State.cpp: Implements the State class, encapsulating raw GL state.
 
 #include "libANGLE/State.h"
 
+#include <string.h>
 #include <limits>
-#include <string.h>
 
 #include "common/bitset_utils.h"
 #include "common/mathutil.h"
 #include "common/matrix_utils.h"
 #include "libANGLE/Caps.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/Debug.h"
 #include "libANGLE/Framebuffer.h"
@@ -33,16 +33,42 @@ GLenum ActiveQueryType(const GLenum type
     return (type == GL_ANY_SAMPLES_PASSED_CONSERVATIVE) ? GL_ANY_SAMPLES_PASSED : type;
 }
 
 }  // anonymous namepace
 
 namespace gl
 {
 
+void UpdateBufferBinding(const Context *context,
+                         BindingPointer<Buffer> *binding,
+                         Buffer *buffer,
+                         BufferBinding target)
+{
+    if (binding->get())
+        (*binding)->onBindingChanged(false, target);
+    binding->set(context, buffer);
+    if (binding->get())
+        (*binding)->onBindingChanged(true, target);
+}
+
+void UpdateBufferBinding(const Context *context,
+                         OffsetBindingPointer<Buffer> *binding,
+                         Buffer *buffer,
+                         BufferBinding target,
+                         GLintptr offset,
+                         GLsizeiptr size)
+{
+    if (binding->get())
+        (*binding)->onBindingChanged(false, target);
+    binding->set(context, buffer, offset, size);
+    if (binding->get())
+        (*binding)->onBindingChanged(true, target);
+}
+
 State::State()
     : mMaxDrawBuffers(0),
       mMaxCombinedTextureImageUnits(0),
       mDepthClearValue(0),
       mStencilClearValue(0),
       mScissorTest(false),
       mSampleCoverage(false),
       mSampleCoverageValue(0),
@@ -78,106 +104,106 @@ State::~State()
 
 void State::initialize(const Context *context,
                        bool debug,
                        bool bindGeneratesResource,
                        bool clientArraysEnabled,
                        bool robustResourceInit,
                        bool programBinaryCacheEnabled)
 {
-    const Caps &caps             = context->getCaps();
-    const Extensions &extensions = context->getExtensions();
+    const Caps &caps                   = context->getCaps();
+    const Extensions &extensions       = context->getExtensions();
     const Extensions &nativeExtensions = context->getImplementation()->getNativeExtensions();
-    const Version &clientVersion = context->getClientVersion();
+    const Version &clientVersion       = context->getClientVersion();
 
-    mMaxDrawBuffers = caps.maxDrawBuffers;
+    mMaxDrawBuffers               = caps.maxDrawBuffers;
     mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
 
     setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
 
-    mDepthClearValue = 1.0f;
+    mDepthClearValue   = 1.0f;
     mStencilClearValue = 0;
 
-    mScissorTest = false;
-    mScissor.x = 0;
-    mScissor.y = 0;
-    mScissor.width = 0;
+    mScissorTest    = false;
+    mScissor.x      = 0;
+    mScissor.y      = 0;
+    mScissor.width  = 0;
     mScissor.height = 0;
 
-    mBlendColor.red = 0;
+    mBlendColor.red   = 0;
     mBlendColor.green = 0;
-    mBlendColor.blue = 0;
+    mBlendColor.blue  = 0;
     mBlendColor.alpha = 0;
 
-    mStencilRef = 0;
+    mStencilRef     = 0;
     mStencilBackRef = 0;
 
-    mSampleCoverage = false;
-    mSampleCoverageValue = 1.0f;
+    mSampleCoverage       = false;
+    mSampleCoverageValue  = 1.0f;
     mSampleCoverageInvert = false;
 
     mMaxSampleMaskWords = caps.maxSampleMaskWords;
     mSampleMask         = false;
     mSampleMaskValues.fill(~GLbitfield(0));
 
-    mGenerateMipmapHint = GL_DONT_CARE;
+    mGenerateMipmapHint           = GL_DONT_CARE;
     mFragmentShaderDerivativeHint = GL_DONT_CARE;
 
     mBindGeneratesResource = bindGeneratesResource;
     mClientArraysEnabled   = clientArraysEnabled;
 
     mLineWidth = 1.0f;
 
-    mViewport.x = 0;
-    mViewport.y = 0;
-    mViewport.width = 0;
+    mViewport.x      = 0;
+    mViewport.y      = 0;
+    mViewport.width  = 0;
     mViewport.height = 0;
-    mNearZ = 0.0f;
-    mFarZ = 1.0f;
+    mNearZ           = 0.0f;
+    mFarZ            = 1.0f;
 
-    mBlend.colorMaskRed = true;
+    mBlend.colorMaskRed   = true;
     mBlend.colorMaskGreen = true;
-    mBlend.colorMaskBlue = true;
+    mBlend.colorMaskBlue  = true;
     mBlend.colorMaskAlpha = true;
 
     mActiveSampler = 0;
 
     mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
 
     // Set all indexes in state attributes type mask to float (default)
     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
     {
         mCurrentValuesTypeMask.setIndex(GL_FLOAT, i);
     }
 
     mUniformBuffers.resize(caps.maxUniformBufferBindings);
 
-    mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
-    mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
+    mSamplerTextures[TextureType::_2D].resize(caps.maxCombinedTextureImageUnits);
+    mSamplerTextures[TextureType::CubeMap].resize(caps.maxCombinedTextureImageUnits);
     if (clientVersion >= Version(3, 0))
     {
         // TODO: These could also be enabled via extension
-        mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
-        mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
+        mSamplerTextures[TextureType::_2DArray].resize(caps.maxCombinedTextureImageUnits);
+        mSamplerTextures[TextureType::_3D].resize(caps.maxCombinedTextureImageUnits);
     }
     if (clientVersion >= Version(3, 1))
     {
-        mSamplerTextures[GL_TEXTURE_2D_MULTISAMPLE].resize(caps.maxCombinedTextureImageUnits);
+        mSamplerTextures[TextureType::_2DMultisample].resize(caps.maxCombinedTextureImageUnits);
 
         mAtomicCounterBuffers.resize(caps.maxAtomicCounterBufferBindings);
         mShaderStorageBuffers.resize(caps.maxShaderStorageBufferBindings);
         mImageUnits.resize(caps.maxImageUnits);
     }
     if (nativeExtensions.textureRectangle)
     {
-        mSamplerTextures[GL_TEXTURE_RECTANGLE_ANGLE].resize(caps.maxCombinedTextureImageUnits);
+        mSamplerTextures[TextureType::Rectangle].resize(caps.maxCombinedTextureImageUnits);
     }
     if (nativeExtensions.eglImageExternal || nativeExtensions.eglStreamConsumerExternal)
     {
-        mSamplerTextures[GL_TEXTURE_EXTERNAL_OES].resize(caps.maxCombinedTextureImageUnits);
+        mSamplerTextures[TextureType::External].resize(caps.maxCombinedTextureImageUnits);
     }
     mCompleteTextureCache.resize(caps.maxCombinedTextureImageUnits, nullptr);
     mCompleteTextureBindings.reserve(caps.maxCombinedTextureImageUnits);
     mCachedTexturesInitState = InitState::MayNeedInit;
     for (uint32_t textureIndex = 0; textureIndex < caps.maxCombinedTextureImageUnits;
          ++textureIndex)
     {
         mCompleteTextureBindings.emplace_back(this, textureIndex);
@@ -185,16 +211,17 @@ void State::initialize(const Context *co
 
     mSamplers.resize(caps.maxCombinedTextureImageUnits);
 
     mActiveQueries[GL_ANY_SAMPLES_PASSED].set(context, nullptr);
     mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(context, nullptr);
     mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(context, nullptr);
     mActiveQueries[GL_TIME_ELAPSED_EXT].set(context, nullptr);
     mActiveQueries[GL_COMMANDS_COMPLETED_CHROMIUM].set(context, nullptr);
+    mActiveQueries[GL_PRIMITIVES_GENERATED_EXT].set(context, nullptr);
 
     mProgram = nullptr;
 
     mReadFramebuffer = nullptr;
     mDrawFramebuffer = nullptr;
 
     mPrimitiveRestart = false;
 
@@ -207,28 +234,34 @@ void State::initialize(const Context *co
     mCoverageModulation = GL_NONE;
 
     angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
     angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
     mPathStencilFunc = GL_ALWAYS;
     mPathStencilRef  = 0;
     mPathStencilMask = std::numeric_limits<GLuint>::max();
 
-    mRobustResourceInit = robustResourceInit;
+    mRobustResourceInit        = robustResourceInit;
     mProgramBinaryCacheEnabled = programBinaryCacheEnabled;
+
+    // GLES1 emulation: Initialize state for GLES1 if version
+    // applies
+    if (clientVersion < Version(2, 0))
+    {
+        mGLES1State.initialize(context, this);
+    }
 }
 
 void State::reset(const Context *context)
 {
     for (auto &bindingVec : mSamplerTextures)
     {
-        TextureBindingVector &textureVector = bindingVec.second;
-        for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
+        for (size_t textureIdx = 0; textureIdx < bindingVec.size(); textureIdx++)
         {
-            textureVector[textureIdx].set(context, nullptr);
+            bindingVec[textureIdx].set(context, nullptr);
         }
     }
     for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
     {
         mSamplers[samplerIdx].set(context, nullptr);
     }
 
     for (auto &imageUnit : mImageUnits)
@@ -240,47 +273,49 @@ void State::reset(const Context *context
         imageUnit.access  = GL_READ_ONLY;
         imageUnit.format  = GL_R32UI;
     }
 
     mRenderbuffer.set(context, nullptr);
 
     for (auto type : angle::AllEnums<BufferBinding>())
     {
-        mBoundBuffers[type].set(context, nullptr);
+        UpdateBufferBinding(context, &mBoundBuffers[type], nullptr, type);
     }
 
     if (mProgram)
     {
         mProgram->release(context);
     }
     mProgram = nullptr;
 
     mProgramPipeline.set(context, nullptr);
 
+    if (mTransformFeedback.get())
+        mTransformFeedback->onBindingChanged(false);
     mTransformFeedback.set(context, nullptr);
 
     for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
     {
         i->second.set(context, nullptr);
     }
 
     for (auto &buf : mUniformBuffers)
     {
-        buf.set(context, nullptr);
+        UpdateBufferBinding(context, &buf, nullptr, BufferBinding::Uniform);
     }
 
     for (auto &buf : mAtomicCounterBuffers)
     {
-        buf.set(context, nullptr);
+        UpdateBufferBinding(context, &buf, nullptr, BufferBinding::AtomicCounter);
     }
 
     for (auto &buf : mShaderStorageBuffers)
     {
-        buf.set(context, nullptr);
+        UpdateBufferBinding(context, &buf, nullptr, BufferBinding::ShaderStorage);
     }
 
     angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
     angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
     mPathStencilFunc = GL_ALWAYS;
     mPathStencilRef  = 0;
     mPathStencilMask = std::numeric_limits<GLuint>::max();
 
@@ -300,19 +335,19 @@ const BlendState &State::getBlendState()
 
 const DepthStencilState &State::getDepthStencilState() const
 {
     return mDepthStencil;
 }
 
 void State::setColorClearValue(float red, float green, float blue, float alpha)
 {
-    mColorClearValue.red = red;
+    mColorClearValue.red   = red;
     mColorClearValue.green = green;
-    mColorClearValue.blue = blue;
+    mColorClearValue.blue  = blue;
     mColorClearValue.alpha = alpha;
     mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
 }
 
 void State::setDepthClearValue(float depth)
 {
     mDepthClearValue = depth;
     mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
@@ -321,19 +356,19 @@ void State::setDepthClearValue(float dep
 void State::setStencilClearValue(int stencil)
 {
     mStencilClearValue = stencil;
     mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
 }
 
 void State::setColorMask(bool red, bool green, bool blue, bool alpha)
 {
-    mBlend.colorMaskRed = red;
+    mBlend.colorMaskRed   = red;
     mBlend.colorMaskGreen = green;
-    mBlend.colorMaskBlue = blue;
+    mBlend.colorMaskBlue  = blue;
     mBlend.colorMaskAlpha = alpha;
     mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
 }
 
 void State::setDepthMask(bool mask)
 {
     mDepthStencil.depthMask = mask;
     mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
@@ -381,24 +416,24 @@ bool State::isDepthTestEnabled() const
 void State::setDepthTest(bool enabled)
 {
     mDepthStencil.depthTest = enabled;
     mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
 }
 
 void State::setDepthFunc(GLenum depthFunc)
 {
-     mDepthStencil.depthFunc = depthFunc;
-     mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
+    mDepthStencil.depthFunc = depthFunc;
+    mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
 }
 
 void State::setDepthRange(float zNear, float zFar)
 {
     mNearZ = zNear;
-    mFarZ = zFar;
+    mFarZ  = zFar;
     mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
 }
 
 float State::getNearPlane() const
 {
     return mNearZ;
 }
 
@@ -415,35 +450,35 @@ bool State::isBlendEnabled() const
 void State::setBlend(bool enabled)
 {
     mBlend.blend = enabled;
     mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
 }
 
 void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
 {
-    mBlend.sourceBlendRGB = sourceRGB;
-    mBlend.destBlendRGB = destRGB;
+    mBlend.sourceBlendRGB   = sourceRGB;
+    mBlend.destBlendRGB     = destRGB;
     mBlend.sourceBlendAlpha = sourceAlpha;
-    mBlend.destBlendAlpha = destAlpha;
+    mBlend.destBlendAlpha   = destAlpha;
     mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
 }
 
 void State::setBlendColor(float red, float green, float blue, float alpha)
 {
-    mBlendColor.red = red;
+    mBlendColor.red   = red;
     mBlendColor.green = green;
-    mBlendColor.blue = blue;
+    mBlendColor.blue  = blue;
     mBlendColor.alpha = alpha;
     mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
 }
 
 void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
 {
-    mBlend.blendEquationRGB = rgbEquation;
+    mBlend.blendEquationRGB   = rgbEquation;
     mBlend.blendEquationAlpha = alphaEquation;
     mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
 }
 
 const ColorF &State::getBlendColor() const
 {
     return mBlendColor;
 }
@@ -457,52 +492,58 @@ void State::setStencilTest(bool enabled)
 {
     mDepthStencil.stencilTest = enabled;
     mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
 }
 
 void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
 {
     mDepthStencil.stencilFunc = stencilFunc;
-    mStencilRef = (stencilRef > 0) ? stencilRef : 0;
+    mStencilRef               = (stencilRef > 0) ? stencilRef : 0;
     mDepthStencil.stencilMask = stencilMask;
     mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
 }
 
-void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
+void State::setStencilBackParams(GLenum stencilBackFunc,
+                                 GLint stencilBackRef,
+                                 GLuint stencilBackMask)
 {
     mDepthStencil.stencilBackFunc = stencilBackFunc;
-    mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
+    mStencilBackRef               = (stencilBackRef > 0) ? stencilBackRef : 0;
     mDepthStencil.stencilBackMask = stencilBackMask;
     mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
 }
 
 void State::setStencilWritemask(GLuint stencilWritemask)
 {
     mDepthStencil.stencilWritemask = stencilWritemask;
     mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
 }
 
 void State::setStencilBackWritemask(GLuint stencilBackWritemask)
 {
     mDepthStencil.stencilBackWritemask = stencilBackWritemask;
     mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
 }
 
-void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
+void State::setStencilOperations(GLenum stencilFail,
+                                 GLenum stencilPassDepthFail,
+                                 GLenum stencilPassDepthPass)
 {
-    mDepthStencil.stencilFail = stencilFail;
+    mDepthStencil.stencilFail          = stencilFail;
     mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
     mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
     mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
 }
 
-void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
+void State::setStencilBackOperations(GLenum stencilBackFail,
+                                     GLenum stencilBackPassDepthFail,
+                                     GLenum stencilBackPassDepthPass)
 {
-    mDepthStencil.stencilBackFail = stencilBackFail;
+    mDepthStencil.stencilBackFail          = stencilBackFail;
     mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
     mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
     mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
 }
 
 GLint State::getStencilRef() const
 {
     return mStencilRef;
@@ -523,17 +564,17 @@ void State::setPolygonOffsetFill(bool en
     mRasterizer.polygonOffsetFill = enabled;
     mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
 }
 
 void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
 {
     // An application can pass NaN values here, so handle this gracefully
     mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
-    mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
+    mRasterizer.polygonOffsetUnits  = units != units ? 0.0f : units;
     mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
 }
 
 bool State::isSampleAlphaToCoverageEnabled() const
 {
     return mBlend.sampleAlphaToCoverage;
 }
 
@@ -551,17 +592,17 @@ bool State::isSampleCoverageEnabled() co
 void State::setSampleCoverage(bool enabled)
 {
     mSampleCoverage = enabled;
     mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
 }
 
 void State::setSampleCoverageParams(GLclampf value, bool invert)
 {
-    mSampleCoverageValue = value;
+    mSampleCoverageValue  = value;
     mSampleCoverageInvert = invert;
     mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
 }
 
 GLclampf State::getSampleCoverageValue() const
 {
     return mSampleCoverageValue;
 }
@@ -631,19 +672,19 @@ bool State::isScissorTestEnabled() const
 void State::setScissorTest(bool enabled)
 {
     mScissorTest = enabled;
     mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
 }
 
 void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
 {
-    mScissor.x = x;
-    mScissor.y = y;
-    mScissor.width = width;
+    mScissor.x      = x;
+    mScissor.y      = y;
+    mScissor.width  = width;
     mScissor.height = height;
     mDirtyBits.set(DIRTY_BIT_SCISSOR);
 }
 
 const Rectangle &State::getScissor() const
 {
     return mScissor;
 }
@@ -669,82 +710,132 @@ void State::setPrimitiveRestart(bool ena
     mPrimitiveRestart = enabled;
     mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
 }
 
 void State::setEnableFeature(GLenum feature, bool enabled)
 {
     switch (feature)
     {
-      case GL_MULTISAMPLE_EXT:               setMultisampling(enabled);         break;
-      case GL_SAMPLE_ALPHA_TO_ONE_EXT:       setSampleAlphaToOne(enabled);      break;
-      case GL_CULL_FACE:                     setCullFace(enabled);              break;
-      case GL_POLYGON_OFFSET_FILL:           setPolygonOffsetFill(enabled);     break;
-      case GL_SAMPLE_ALPHA_TO_COVERAGE:      setSampleAlphaToCoverage(enabled); break;
-      case GL_SAMPLE_COVERAGE:               setSampleCoverage(enabled);        break;
-      case GL_SCISSOR_TEST:                  setScissorTest(enabled);           break;
-      case GL_STENCIL_TEST:                  setStencilTest(enabled);           break;
-      case GL_DEPTH_TEST:                    setDepthTest(enabled);             break;
-      case GL_BLEND:                         setBlend(enabled);                 break;
-      case GL_DITHER:                        setDither(enabled);                break;
-      case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled);      break;
-      case GL_RASTERIZER_DISCARD:            setRasterizerDiscard(enabled);     break;
-      case GL_SAMPLE_MASK:
-          setSampleMaskEnabled(enabled);
-          break;
-      case GL_DEBUG_OUTPUT_SYNCHRONOUS:
-          mDebug.setOutputSynchronous(enabled);
-          break;
-      case GL_DEBUG_OUTPUT:
-          mDebug.setOutputEnabled(enabled);
-          break;
-      case GL_FRAMEBUFFER_SRGB_EXT:
-          setFramebufferSRGB(enabled);
-          break;
-      default:                               UNREACHABLE();
+        case GL_MULTISAMPLE_EXT:
+            setMultisampling(enabled);
+            break;
+        case GL_SAMPLE_ALPHA_TO_ONE_EXT:
+            setSampleAlphaToOne(enabled);
+            break;
+        case GL_CULL_FACE:
+            setCullFace(enabled);
+            break;
+        case GL_POLYGON_OFFSET_FILL:
+            setPolygonOffsetFill(enabled);
+            break;
+        case GL_SAMPLE_ALPHA_TO_COVERAGE:
+            setSampleAlphaToCoverage(enabled);
+            break;
+        case GL_SAMPLE_COVERAGE:
+            setSampleCoverage(enabled);
+            break;
+        case GL_SCISSOR_TEST:
+            setScissorTest(enabled);
+            break;
+        case GL_STENCIL_TEST:
+            setStencilTest(enabled);
+            break;
+        case GL_DEPTH_TEST:
+            setDepthTest(enabled);
+            break;
+        case GL_BLEND:
+            setBlend(enabled);
+            break;
+        case GL_DITHER:
+            setDither(enabled);
+            break;
+        case GL_PRIMITIVE_RESTART_FIXED_INDEX:
+            setPrimitiveRestart(enabled);
+            break;
+        case GL_RASTERIZER_DISCARD:
+            setRasterizerDiscard(enabled);
+            break;
+        case GL_SAMPLE_MASK:
+            setSampleMaskEnabled(enabled);
+            break;
+        case GL_DEBUG_OUTPUT_SYNCHRONOUS:
+            mDebug.setOutputSynchronous(enabled);
+            break;
+        case GL_DEBUG_OUTPUT:
+            mDebug.setOutputEnabled(enabled);
+            break;
+        case GL_FRAMEBUFFER_SRGB_EXT:
+            setFramebufferSRGB(enabled);
+            break;
+
+        // GLES1 emulation
+        case GL_ALPHA_TEST:
+            mGLES1State.mAlphaTestEnabled = enabled;
+            break;
+
+        default:
+            UNREACHABLE();
     }
 }
 
 bool State::getEnableFeature(GLenum feature) const
 {
     switch (feature)
     {
-      case GL_MULTISAMPLE_EXT:               return isMultisamplingEnabled();
-      case GL_SAMPLE_ALPHA_TO_ONE_EXT:       return isSampleAlphaToOneEnabled();
-      case GL_CULL_FACE:                     return isCullFaceEnabled();
-      case GL_POLYGON_OFFSET_FILL:           return isPolygonOffsetFillEnabled();
-      case GL_SAMPLE_ALPHA_TO_COVERAGE:      return isSampleAlphaToCoverageEnabled();
-      case GL_SAMPLE_COVERAGE:               return isSampleCoverageEnabled();
-      case GL_SCISSOR_TEST:                  return isScissorTestEnabled();
-      case GL_STENCIL_TEST:                  return isStencilTestEnabled();
-      case GL_DEPTH_TEST:                    return isDepthTestEnabled();
-      case GL_BLEND:                         return isBlendEnabled();
-      case GL_DITHER:                        return isDitherEnabled();
-      case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
-      case GL_RASTERIZER_DISCARD:            return isRasterizerDiscardEnabled();
-      case GL_SAMPLE_MASK:
-          return isSampleMaskEnabled();
-      case GL_DEBUG_OUTPUT_SYNCHRONOUS:
-          return mDebug.isOutputSynchronous();
-      case GL_DEBUG_OUTPUT:
-          return mDebug.isOutputEnabled();
-      case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
-          return isBindGeneratesResourceEnabled();
-      case GL_CLIENT_ARRAYS_ANGLE:
-          return areClientArraysEnabled();
-      case GL_FRAMEBUFFER_SRGB_EXT:
-          return getFramebufferSRGB();
-      case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
-          return mRobustResourceInit;
-      case GL_PROGRAM_CACHE_ENABLED_ANGLE:
-          return mProgramBinaryCacheEnabled;
+        case GL_MULTISAMPLE_EXT:
+            return isMultisamplingEnabled();
+        case GL_SAMPLE_ALPHA_TO_ONE_EXT:
+            return isSampleAlphaToOneEnabled();
+        case GL_CULL_FACE:
+            return isCullFaceEnabled();
+        case GL_POLYGON_OFFSET_FILL:
+            return isPolygonOffsetFillEnabled();
+        case GL_SAMPLE_ALPHA_TO_COVERAGE:
+            return isSampleAlphaToCoverageEnabled();
+        case GL_SAMPLE_COVERAGE:
+            return isSampleCoverageEnabled();
+        case GL_SCISSOR_TEST:
+            return isScissorTestEnabled();
+        case GL_STENCIL_TEST:
+            return isStencilTestEnabled();
+        case GL_DEPTH_TEST:
+            return isDepthTestEnabled();
+        case GL_BLEND:
+            return isBlendEnabled();
+        case GL_DITHER:
+            return isDitherEnabled();
+        case GL_PRIMITIVE_RESTART_FIXED_INDEX:
+            return isPrimitiveRestartEnabled();
+        case GL_RASTERIZER_DISCARD:
+            return isRasterizerDiscardEnabled();
+        case GL_SAMPLE_MASK:
+            return isSampleMaskEnabled();
+        case GL_DEBUG_OUTPUT_SYNCHRONOUS:
+            return mDebug.isOutputSynchronous();
+        case GL_DEBUG_OUTPUT:
+            return mDebug.isOutputEnabled();
+        case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
+            return isBindGeneratesResourceEnabled();
+        case GL_CLIENT_ARRAYS_ANGLE:
+            return areClientArraysEnabled();
+        case GL_FRAMEBUFFER_SRGB_EXT:
+            return getFramebufferSRGB();
+        case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+            return mRobustResourceInit;
+        case GL_PROGRAM_CACHE_ENABLED_ANGLE:
+            return mProgramBinaryCacheEnabled;
 
-      default:
-          UNREACHABLE();
-          return false;
+        // GLES1 emulation
+        case GL_ALPHA_TEST:
+            return mGLES1State.mAlphaTestEnabled;
+
+        default:
+            UNREACHABLE();
+            return false;
     }
 }
 
 void State::setLineWidth(GLfloat width)
 {
     mLineWidth = width;
     mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
 }
@@ -776,19 +867,19 @@ bool State::isBindGeneratesResourceEnabl
 
 bool State::areClientArraysEnabled() const
 {
     return mClientArraysEnabled;
 }
 
 void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
 {
-    mViewport.x = x;
-    mViewport.y = y;
-    mViewport.width = width;
+    mViewport.x      = x;
+    mViewport.y      = y;
+    mViewport.width  = width;
     mViewport.height = height;
     mDirtyBits.set(DIRTY_BIT_VIEWPORT);
 }
 
 const Rectangle &State::getViewport() const
 {
     return mViewport;
 }
@@ -798,67 +889,62 @@ void State::setActiveSampler(unsigned in
     mActiveSampler = active;
 }
 
 unsigned int State::getActiveSampler() const
 {
     return static_cast<unsigned int>(mActiveSampler);
 }
 
-void State::setSamplerTexture(const Context *context, GLenum type, Texture *texture)
+void State::setSamplerTexture(const Context *context, TextureType type, Texture *texture)
 {
     mSamplerTextures[type][mActiveSampler].set(context, texture);
     mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
     mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
 }
 
-Texture *State::getTargetTexture(GLenum target) const
+Texture *State::getTargetTexture(TextureType type) const
 {
-    return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), target);
+    return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), type);
 }
 
-Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
+Texture *State::getSamplerTexture(unsigned int sampler, TextureType type) const
 {
-    const auto it = mSamplerTextures.find(type);
-    ASSERT(it != mSamplerTextures.end());
-    ASSERT(sampler < it->second.size());
-    return it->second[sampler].get();
+    ASSERT(sampler < mSamplerTextures[type].size());
+    return mSamplerTextures[type][sampler].get();
 }
 
-GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
+GLuint State::getSamplerTextureId(unsigned int sampler, TextureType type) const
 {
-    const auto it = mSamplerTextures.find(type);
-    ASSERT(it != mSamplerTextures.end());
-    ASSERT(sampler < it->second.size());
-    return it->second[sampler].id();
+    ASSERT(sampler < mSamplerTextures[type].size());
+    return mSamplerTextures[type][sampler].id();
 }
 
 void State::detachTexture(const Context *context, const TextureMap &zeroTextures, GLuint texture)
 {
     // Textures have a detach method on State rather than a simple
     // removeBinding, because the zero/null texture objects are managed
     // separately, and don't have to go through the Context's maps or
     // the ResourceManager.
 
     // [OpenGL ES 2.0.24] section 3.8 page 84:
-    // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
-    // rebound to texture object zero
+    // If a texture object is deleted, it is as if all texture units which are bound to that texture
+    // object are rebound to texture object zero
 
-    for (auto &bindingVec : mSamplerTextures)
+    for (TextureType type : angle::AllEnums<TextureType>())
     {
-        GLenum textureType = bindingVec.first;
-        TextureBindingVector &textureVector = bindingVec.second;
+        TextureBindingVector &textureVector = mSamplerTextures[type];
         for (BindingPointer<Texture> &binding : textureVector)
         {
             if (binding.id() == texture)
             {
-                auto it = zeroTextures.find(textureType);
-                ASSERT(it != zeroTextures.end());
+                Texture *zeroTexture = zeroTextures[type].get();
+                ASSERT(zeroTexture != nullptr);
                 // Zero textures are the "default" textures instead of NULL
-                binding.set(context, it->second.get());
+                binding.set(context, zeroTexture);
                 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
             }
         }
     }
 
     for (auto &bindingImageUnit : mImageUnits)
     {
         if (bindingImageUnit.texture.id() == texture)
@@ -869,40 +955,38 @@ void State::detachTexture(const Context 
             bindingImageUnit.layer   = 0;
             bindingImageUnit.access  = GL_READ_ONLY;
             bindingImageUnit.format  = GL_R32UI;
             break;
         }
     }
 
     // [OpenGL ES 2.0.24] section 4.4 page 112:
-    // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
-    // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
-    // image was attached in the currently bound framebuffer.
+    // If a texture object is deleted while its image is attached to the currently bound
+    // framebuffer, then it is as if Texture2DAttachment had been called, with a texture of 0, for
+    // each attachment point to which this image was attached in the currently bound framebuffer.
 
     if (mReadFramebuffer && mReadFramebuffer->detachTexture(context, texture))
     {
         mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
     }
 
     if (mDrawFramebuffer && mDrawFramebuffer->detachTexture(context, texture))
     {
         mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
     }
 }
 
 void State::initializeZeroTextures(const Context *context, const TextureMap &zeroTextures)
 {
-    for (const auto &zeroTexture : zeroTextures)
+    for (TextureType type : angle::AllEnums<TextureType>())
     {
-        auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
-
-        for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
+        for (size_t textureUnit = 0; textureUnit < mSamplerTextures[type].size(); ++textureUnit)
         {
-            samplerTextureArray[textureUnit].set(context, zeroTexture.second.get());
+            mSamplerTextures[type][textureUnit].set(context, zeroTextures[type].get());
         }
     }
 }
 
 void State::setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler)
 {
     mSamplers[textureUnit].set(context, sampler);
     mDirtyBits.set(DIRTY_BIT_SAMPLER_BINDINGS);
@@ -950,45 +1034,45 @@ GLuint State::getRenderbufferId() const
 Renderbuffer *State::getCurrentRenderbuffer() const
 {
     return mRenderbuffer.get();
 }
 
 void State::detachRenderbuffer(const Context *context, GLuint renderbuffer)
 {
     // [OpenGL ES 2.0.24] section 4.4 page 109:
-    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
-    // had been executed with the target RENDERBUFFER and name of zero.
+    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though
+    // BindRenderbuffer had been executed with the target RENDERBUFFER and name of zero.
 
     if (mRenderbuffer.id() == renderbuffer)
     {
         setRenderbufferBinding(context, nullptr);
     }
 
     // [OpenGL ES 2.0.24] section 4.4 page 111:
-    // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
-    // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
-    // point to which this image was attached in the currently bound framebuffer.
+    // If a renderbuffer object is deleted while its image is attached to the currently bound
+    // framebuffer, then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of
+    // 0, for each attachment point to which this image was attached in the currently bound
+    // framebuffer.
 
     Framebuffer *readFramebuffer = mReadFramebuffer;
     Framebuffer *drawFramebuffer = mDrawFramebuffer;
 
     if (readFramebuffer && readFramebuffer->detachRenderbuffer(context, renderbuffer))
     {
         mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
     }
 
     if (drawFramebuffer && drawFramebuffer != readFramebuffer)
     {
         if (drawFramebuffer->detachRenderbuffer(context, renderbuffer))
         {
             mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
         }
     }
-
 }
 
 void State::setReadFramebufferBinding(Framebuffer *framebuffer)
 {
     if (mReadFramebuffer == framebuffer)
         return;
 
     mReadFramebuffer = framebuffer;
@@ -1036,41 +1120,45 @@ Framebuffer *State::getReadFramebuffer()
 
 Framebuffer *State::getDrawFramebuffer() const
 {
     return mDrawFramebuffer;
 }
 
 bool State::removeReadFramebufferBinding(GLuint framebuffer)
 {
-    if (mReadFramebuffer != nullptr &&
-        mReadFramebuffer->id() == framebuffer)
+    if (mReadFramebuffer != nullptr && mReadFramebuffer->id() == framebuffer)
     {
         setReadFramebufferBinding(nullptr);
         return true;
     }
 
     return false;
 }
 
 bool State::removeDrawFramebufferBinding(GLuint framebuffer)
 {
-    if (mReadFramebuffer != nullptr &&
-        mDrawFramebuffer->id() == framebuffer)
+    if (mReadFramebuffer != nullptr && mDrawFramebuffer->id() == framebuffer)
     {
         setDrawFramebufferBinding(nullptr);
         return true;
     }
 
     return false;
 }
 
 void State::setVertexArrayBinding(VertexArray *vertexArray)
 {
+    if (mVertexArray == vertexArray)
+        return;
+    if (mVertexArray)
+        mVertexArray->onBindingChanged(false);
     mVertexArray = vertexArray;
+    if (vertexArray)
+        vertexArray->onBindingChanged(true);
     mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
 
     if (mVertexArray && mVertexArray->hasAnyDirtyBit())
     {
         mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
     }
 }
 
@@ -1083,18 +1171,19 @@ GLuint State::getVertexArrayId() const
 VertexArray *State::getVertexArray() const
 {
     ASSERT(mVertexArray != nullptr);
     return mVertexArray;
 }
 
 bool State::removeVertexArrayBinding(GLuint vertexArray)
 {
-    if (mVertexArray->id() == vertexArray)
+    if (mVertexArray && mVertexArray->id() == vertexArray)
     {
+        mVertexArray->onBindingChanged(false);
         mVertexArray = nullptr;
         mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
         mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
         return true;
     }
 
     return false;
 }
@@ -1157,35 +1246,44 @@ void State::setProgram(const Context *co
 Program *State::getProgram() const
 {
     return mProgram;
 }
 
 void State::setTransformFeedbackBinding(const Context *context,
                                         TransformFeedback *transformFeedback)
 {
+    if (transformFeedback == mTransformFeedback.get())
+        return;
+    if (mTransformFeedback.get())
+        mTransformFeedback->onBindingChanged(false);
     mTransformFeedback.set(context, transformFeedback);
+    if (mTransformFeedback.get())
+        mTransformFeedback->onBindingChanged(true);
     mDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
 }
 
 TransformFeedback *State::getCurrentTransformFeedback() const
 {
     return mTransformFeedback.get();
 }
 
 bool State::isTransformFeedbackActiveUnpaused() const
 {
     TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
-    return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
+    return curTransformFeedback && curTransformFeedback->isActive() &&
+           !curTransformFeedback->isPaused();
 }
 
 bool State::removeTransformFeedbackBinding(const Context *context, GLuint transformFeedback)
 {
     if (mTransformFeedback.id() == transformFeedback)
     {
+        if (mTransformFeedback.get())
+            mTransformFeedback->onBindingChanged(false);
         mTransformFeedback.set(context, nullptr);
         return true;
     }
 
     return false;
 }
 
 void State::setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline)
@@ -1246,73 +1344,71 @@ Query *State::getActiveQuery(GLenum targ
     return it->second.get();
 }
 
 void State::setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer)
 {
     switch (target)
     {
         case BufferBinding::PixelPack:
-            mBoundBuffers[target].set(context, buffer);
+            UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target);
             mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING);
             break;
         case BufferBinding::PixelUnpack:
-            mBoundBuffers[target].set(context, buffer);
+            UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target);
             mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING);
             break;
         case BufferBinding::DrawIndirect:
-            mBoundBuffers[target].set(context, buffer);
+            UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target);
             mDirtyBits.set(DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING);
             break;
         case BufferBinding::DispatchIndirect:
-            mBoundBuffers[target].set(context, buffer);
+            UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target);
             mDirtyBits.set(DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING);
             break;
-        case BufferBinding::TransformFeedback:
-            if (mTransformFeedback.get() != nullptr)
-            {
-                mTransformFeedback->bindGenericBuffer(context, buffer);
-            }
-            break;
         case BufferBinding::ElementArray:
             getVertexArray()->setElementArrayBuffer(context, buffer);
             mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
             break;
         case BufferBinding::ShaderStorage:
-            mBoundBuffers[target].set(context, buffer);
+            UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target);
             mDirtyBits.set(DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
             break;
         default:
-            mBoundBuffers[target].set(context, buffer);
+            UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target);
             break;
     }
 }
+
 void State::setIndexedBufferBinding(const Context *context,
                                     BufferBinding target,
                                     GLuint index,
                                     Buffer *buffer,
                                     GLintptr offset,
                                     GLsizeiptr size)
 {
     setBufferBinding(context, target, buffer);
 
     switch (target)
     {
         case BufferBinding::TransformFeedback:
             mTransformFeedback->bindIndexedBuffer(context, index, buffer, offset, size);
+            setBufferBinding(context, target, buffer);
             break;
         case BufferBinding::Uniform:
-            mUniformBuffers[index].set(context, buffer, offset, size);
+            UpdateBufferBinding(context, &mUniformBuffers[index], buffer, target, offset, size);
             mDirtyBits.set(DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
             break;
         case BufferBinding::AtomicCounter:
-            mAtomicCounterBuffers[index].set(context, buffer, offset, size);
+            UpdateBufferBinding(context, &mAtomicCounterBuffers[index], buffer, target, offset,
+                                size);
             break;
         case BufferBinding::ShaderStorage:
-            mShaderStorageBuffers[index].set(context, buffer, offset, size);
+            UpdateBufferBinding(context, &mShaderStorageBuffers[index], buffer, target, offset,
+                                size);
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
 const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
@@ -1334,40 +1430,67 @@ const OffsetBindingPointer<Buffer> &Stat
 }
 
 Buffer *State::getTargetBuffer(BufferBinding target) const
 {
     switch (target)
     {
         case BufferBinding::ElementArray:
             return getVertexArray()->getElementArrayBuffer().get();
-        case BufferBinding::TransformFeedback:
-            return mTransformFeedback->getGenericBuffer().get();
         default:
             return mBoundBuffers[target].get();
     }
 }
 
-void State::detachBuffer(const Context *context, GLuint bufferName)
+void State::detachBuffer(const Context *context, const Buffer *buffer)
 {
-    for (auto &buffer : mBoundBuffers)
+    if (!buffer->isBound())
     {
-        if (buffer.id() == bufferName)
+        return;
+    }
+    GLuint bufferName = buffer->id();
+    for (auto target : angle::AllEnums<BufferBinding>())
+    {
+        if (mBoundBuffers[target].id() == bufferName)
         {
-            buffer.set(context, nullptr);
+            UpdateBufferBinding(context, &mBoundBuffers[target], nullptr, target);
         }
     }
 
     TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
     if (curTransformFeedback)
     {
         curTransformFeedback->detachBuffer(context, bufferName);
     }
 
     getVertexArray()->detachBuffer(context, bufferName);
+
+    for (auto &buf : mUniformBuffers)
+    {
+        if (buf.id() == bufferName)
+        {
+            UpdateBufferBinding(context, &buf, nullptr, BufferBinding::Uniform);
+        }
+    }
+
+    for (auto &buf : mAtomicCounterBuffers)
+    {
+        if (buf.id() == bufferName)
+        {
+            UpdateBufferBinding(context, &buf, nullptr, BufferBinding::AtomicCounter);
+        }
+    }
+
+    for (auto &buf : mShaderStorageBuffers)
+    {
+        if (buf.id() == bufferName)
+        {
+            UpdateBufferBinding(context, &buf, nullptr, BufferBinding::ShaderStorage);
+        }
+    }
 }
 
 void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
 {
     getVertexArray()->enableAttribute(attribNum, enabled);
     mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
 }
 
@@ -1663,133 +1786,206 @@ bool State::getFramebufferSRGB() const
 {
     return mFramebufferSRGB;
 }
 
 void State::getBooleanv(GLenum pname, GLboolean *params)
 {
     switch (pname)
     {
-      case GL_SAMPLE_COVERAGE_INVERT:    *params = mSampleCoverageInvert;         break;
-      case GL_DEPTH_WRITEMASK:           *params = mDepthStencil.depthMask;       break;
-      case GL_COLOR_WRITEMASK:
-        params[0] = mBlend.colorMaskRed;
-        params[1] = mBlend.colorMaskGreen;
-        params[2] = mBlend.colorMaskBlue;
-        params[3] = mBlend.colorMaskAlpha;
-        break;
-      case GL_CULL_FACE:
-          *params = mRasterizer.cullFace;
-          break;
-      case GL_POLYGON_OFFSET_FILL:       *params = mRasterizer.polygonOffsetFill; break;
-      case GL_SAMPLE_ALPHA_TO_COVERAGE:  *params = mBlend.sampleAlphaToCoverage;  break;
-      case GL_SAMPLE_COVERAGE:           *params = mSampleCoverage;               break;
-      case GL_SAMPLE_MASK:
-          *params = mSampleMask;
-          break;
-      case GL_SCISSOR_TEST:              *params = mScissorTest;                  break;
-      case GL_STENCIL_TEST:              *params = mDepthStencil.stencilTest;     break;
-      case GL_DEPTH_TEST:                *params = mDepthStencil.depthTest;       break;
-      case GL_BLEND:                     *params = mBlend.blend;                  break;
-      case GL_DITHER:                    *params = mBlend.dither;                 break;
-      case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
-      case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
-      case GL_PRIMITIVE_RESTART_FIXED_INDEX:
-          *params = mPrimitiveRestart;
-          break;
-      case GL_RASTERIZER_DISCARD:
-          *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
-          break;
-      case GL_DEBUG_OUTPUT_SYNCHRONOUS:
-          *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
-          break;
-      case GL_DEBUG_OUTPUT:
-          *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
-          break;
-      case GL_MULTISAMPLE_EXT:
-          *params = mMultiSampling;
-          break;
-      case GL_SAMPLE_ALPHA_TO_ONE_EXT:
-          *params = mSampleAlphaToOne;
-          break;
-      case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
-          *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE;
-          break;
-      case GL_CLIENT_ARRAYS_ANGLE:
-          *params = areClientArraysEnabled() ? GL_TRUE : GL_FALSE;
-          break;
-      case GL_FRAMEBUFFER_SRGB_EXT:
-          *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE;
-          break;
-      case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
-          *params = mRobustResourceInit ? GL_TRUE : GL_FALSE;
-          break;
-      case GL_PROGRAM_CACHE_ENABLED_ANGLE:
-          *params = mProgramBinaryCacheEnabled ? GL_TRUE : GL_FALSE;
-          break;
+        case GL_SAMPLE_COVERAGE_INVERT:
+            *params = mSampleCoverageInvert;
+            break;
+        case GL_DEPTH_WRITEMASK:
+            *params = mDepthStencil.depthMask;
+            break;
+        case GL_COLOR_WRITEMASK:
+            params[0] = mBlend.colorMaskRed;
+            params[1] = mBlend.colorMaskGreen;
+            params[2] = mBlend.colorMaskBlue;
+            params[3] = mBlend.colorMaskAlpha;
+            break;
+        case GL_CULL_FACE:
+            *params = mRasterizer.cullFace;
+            break;
+        case GL_POLYGON_OFFSET_FILL:
+            *params = mRasterizer.polygonOffsetFill;
+            break;
+        case GL_SAMPLE_ALPHA_TO_COVERAGE:
+            *params = mBlend.sampleAlphaToCoverage;
+            break;
+        case GL_SAMPLE_COVERAGE:
+            *params = mSampleCoverage;
+            break;
+        case GL_SAMPLE_MASK:
+            *params = mSampleMask;
+            break;
+        case GL_SCISSOR_TEST:
+            *params = mScissorTest;
+            break;
+        case GL_STENCIL_TEST:
+            *params = mDepthStencil.stencilTest;
+            break;
+        case GL_DEPTH_TEST:
+            *params = mDepthStencil.depthTest;
+            break;
+        case GL_BLEND:
+            *params = mBlend.blend;
+            break;
+        case GL_DITHER:
+            *params = mBlend.dither;
+            break;
+        case GL_TRANSFORM_FEEDBACK_ACTIVE:
+            *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE;
+            break;
+        case GL_TRANSFORM_FEEDBACK_PAUSED:
+            *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE;
+            break;
+        case GL_PRIMITIVE_RESTART_FIXED_INDEX:
+            *params = mPrimitiveRestart;
+            break;
+        case GL_RASTERIZER_DISCARD:
+            *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
+            break;
+        case GL_DEBUG_OUTPUT_SYNCHRONOUS:
+            *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
+            break;
+        case GL_DEBUG_OUTPUT:
+            *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
+            break;
+        case GL_MULTISAMPLE_EXT:
+            *params = mMultiSampling;
+            break;
+        case GL_SAMPLE_ALPHA_TO_ONE_EXT:
+            *params = mSampleAlphaToOne;
+            break;
+        case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
+            *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE;
+            break;
+        case GL_CLIENT_ARRAYS_ANGLE:
+            *params = areClientArraysEnabled() ? GL_TRUE : GL_FALSE;
+            break;
+        case GL_FRAMEBUFFER_SRGB_EXT:
+            *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE;
+            break;
+        case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+            *params = mRobustResourceInit ? GL_TRUE : GL_FALSE;
+            break;
+        case GL_PROGRAM_CACHE_ENABLED_ANGLE:
+            *params = mProgramBinaryCacheEnabled ? GL_TRUE : GL_FALSE;
+            break;
 
-      default:
-        UNREACHABLE();
-        break;
+        default:
+            UNREACHABLE();
+            break;
     }
 }
 
 void State::getFloatv(GLenum pname, GLfloat *params)
 {
     // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
     // GetIntegerv as its native query function. As it would require conversion in any
     // case, this should make no difference to the calling application.
     switch (pname)
     {
-      case GL_LINE_WIDTH:               *params = mLineWidth;                         break;
-      case GL_SAMPLE_COVERAGE_VALUE:    *params = mSampleCoverageValue;               break;
-      case GL_DEPTH_CLEAR_VALUE:        *params = mDepthClearValue;                   break;
-      case GL_POLYGON_OFFSET_FACTOR:    *params = mRasterizer.polygonOffsetFactor;    break;
-      case GL_POLYGON_OFFSET_UNITS:     *params = mRasterizer.polygonOffsetUnits;     break;
-      case GL_DEPTH_RANGE:
-        params[0] = mNearZ;
-        params[1] = mFarZ;
-        break;
-      case GL_COLOR_CLEAR_VALUE:
-        params[0] = mColorClearValue.red;
-        params[1] = mColorClearValue.green;
-        params[2] = mColorClearValue.blue;
-        params[3] = mColorClearValue.alpha;
-        break;
-      case GL_BLEND_COLOR:
-        params[0] = mBlendColor.red;
-        params[1] = mBlendColor.green;
-        params[2] = mBlendColor.blue;
-        params[3] = mBlendColor.alpha;
-        break;
-      case GL_MULTISAMPLE_EXT:
-        *params = static_cast<GLfloat>(mMultiSampling);
-        break;
-      case GL_SAMPLE_ALPHA_TO_ONE_EXT:
-        *params = static_cast<GLfloat>(mSampleAlphaToOne);
-        break;
-      case GL_COVERAGE_MODULATION_CHROMIUM:
-        params[0] = static_cast<GLfloat>(mCoverageModulation);
-        break;
-      default:
-        UNREACHABLE();
-        break;
+        case GL_LINE_WIDTH:
+            *params = mLineWidth;
+            break;
+        case GL_SAMPLE_COVERAGE_VALUE:
+            *params = mSampleCoverageValue;
+            break;
+        case GL_DEPTH_CLEAR_VALUE:
+            *params = mDepthClearValue;
+            break;
+        case GL_POLYGON_OFFSET_FACTOR:
+            *params = mRasterizer.polygonOffsetFactor;
+            break;
+        case GL_POLYGON_OFFSET_UNITS:
+            *params = mRasterizer.polygonOffsetUnits;
+            break;
+        case GL_DEPTH_RANGE:
+            params[0] = mNearZ;
+            params[1] = mFarZ;
+            break;
+        case GL_COLOR_CLEAR_VALUE:
+            params[0] = mColorClearValue.red;
+            params[1] = mColorClearValue.green;
+            params[2] = mColorClearValue.blue;
+            params[3] = mColorClearValue.alpha;
+            break;
+        case GL_BLEND_COLOR:
+            params[0] = mBlendColor.red;
+            params[1] = mBlendColor.green;
+            params[2] = mBlendColor.blue;
+            params[3] = mBlendColor.alpha;
+            break;
+        case GL_MULTISAMPLE_EXT:
+            *params = static_cast<GLfloat>(mMultiSampling);
+            break;
+        case GL_SAMPLE_ALPHA_TO_ONE_EXT:
+            *params = static_cast<GLfloat>(mSampleAlphaToOne);
+            break;
+        case GL_COVERAGE_MODULATION_CHROMIUM:
+            params[0] = static_cast<GLfloat>(mCoverageModulation);
+            break;
+        case GL_ALPHA_TEST_REF:
+            *params = mGLES1State.mAlphaTestRef;
+            break;
+        case GL_CURRENT_COLOR:
+        {
+            const auto &color = mGLES1State.mCurrentColor;
+            params[0]         = color.red;
+            params[1]         = color.green;
+            params[2]         = color.blue;
+            params[3]         = color.alpha;
+            break;
+        }
+        case GL_CURRENT_NORMAL:
+        {
+            const auto &normal = mGLES1State.mCurrentNormal;
+            params[0]          = normal[0];
+            params[1]          = normal[1];
+            params[2]          = normal[2];
+            break;
+        }
+        case GL_CURRENT_TEXTURE_COORDS:
+        {
+            const auto &texcoord = mGLES1State.mCurrentTextureCoords[mActiveSampler];
+            params[0]            = texcoord.s;
+            params[1]            = texcoord.t;
+            params[2]            = texcoord.r;
+            params[3]            = texcoord.q;
+            break;
+        }
+        case GL_MODELVIEW_MATRIX:
+            memcpy(params, mGLES1State.mModelviewMatrices.back().data(), 16 * sizeof(GLfloat));
+            break;
+        case GL_PROJECTION_MATRIX:
+            memcpy(params, mGLES1State.mProjectionMatrices.back().data(), 16 * sizeof(GLfloat));
+            break;
+        case GL_TEXTURE_MATRIX:
+            memcpy(params, mGLES1State.mTextureMatrices[mActiveSampler].back().data(),
+                   16 * sizeof(GLfloat));
+            break;
+        default:
+            UNREACHABLE();
+            break;
     }
 }
 
-void State::getIntegerv(const Context *context, GLenum pname, GLint *params)
+Error State::getIntegerv(const Context *context, GLenum pname, GLint *params)
 {
     if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
     {
         unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
         ASSERT(colorAttachment < mMaxDrawBuffers);
         Framebuffer *framebuffer = mDrawFramebuffer;
-        *params = framebuffer->getDrawBufferState(colorAttachment);
-        return;
+        *params                  = framebuffer->getDrawBufferState(colorAttachment);
+        return NoError();
     }
 
     // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
     // GetIntegerv as its native query function. As it would require conversion in any
     // case, this should make no difference to the calling application. You may find it in
     // State::getFloatv.
     switch (pname)
@@ -1798,282 +1994,369 @@ void State::getIntegerv(const Context *c
             *params = mBoundBuffers[BufferBinding::Array].id();
             break;
         case GL_DRAW_INDIRECT_BUFFER_BINDING:
             *params = mBoundBuffers[BufferBinding::DrawIndirect].id();
             break;
         case GL_ELEMENT_ARRAY_BUFFER_BINDING:
             *params = getVertexArray()->getElementArrayBuffer().id();
             break;
-        //case GL_FRAMEBUFFER_BINDING:                    // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
-      case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:           *params = mDrawFramebuffer->id();                         break;
-      case GL_READ_FRAMEBUFFER_BINDING_ANGLE:           *params = mReadFramebuffer->id();                         break;
-      case GL_RENDERBUFFER_BINDING:                     *params = mRenderbuffer.id();                             break;
-      case GL_VERTEX_ARRAY_BINDING:                     *params = mVertexArray->id();                             break;
-      case GL_CURRENT_PROGRAM:                          *params = mProgram ? mProgram->id() : 0;                  break;
-      case GL_PACK_ALIGNMENT:                           *params = mPack.alignment;                                break;
-      case GL_PACK_REVERSE_ROW_ORDER_ANGLE:             *params = mPack.reverseRowOrder;                          break;
-      case GL_PACK_ROW_LENGTH:
-          *params = mPack.rowLength;
-          break;
-      case GL_PACK_SKIP_ROWS:
-          *params = mPack.skipRows;
-          break;
-      case GL_PACK_SKIP_PIXELS:
-          *params = mPack.skipPixels;
-          break;
-      case GL_UNPACK_ALIGNMENT:                         *params = mUnpack.alignment;                              break;
-      case GL_UNPACK_ROW_LENGTH:                        *params = mUnpack.rowLength;                              break;
-      case GL_UNPACK_IMAGE_HEIGHT:
-          *params = mUnpack.imageHeight;
-          break;
-      case GL_UNPACK_SKIP_IMAGES:
-          *params = mUnpack.skipImages;
-          break;
-      case GL_UNPACK_SKIP_ROWS:
-          *params = mUnpack.skipRows;
-          break;
-      case GL_UNPACK_SKIP_PIXELS:
-          *params = mUnpack.skipPixels;
-          break;
-      case GL_GENERATE_MIPMAP_HINT:                     *params = mGenerateMipmapHint;                            break;
-      case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:      *params = mFragmentShaderDerivativeHint;                  break;
-      case GL_ACTIVE_TEXTURE:
-          *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
-          break;
-      case GL_STENCIL_FUNC:                             *params = mDepthStencil.stencilFunc;                      break;
-      case GL_STENCIL_REF:                              *params = mStencilRef;                                    break;
-      case GL_STENCIL_VALUE_MASK:
-          *params = CastMaskValue(context, mDepthStencil.stencilMask);
-          break;
-      case GL_STENCIL_BACK_FUNC:                        *params = mDepthStencil.stencilBackFunc;                  break;
-      case GL_STENCIL_BACK_REF:                         *params = mStencilBackRef;                                break;
-      case GL_STENCIL_BACK_VALUE_MASK:
-          *params = CastMaskValue(context, mDepthStencil.stencilBackMask);
-          break;
-      case GL_STENCIL_FAIL:                             *params = mDepthStencil.stencilFail;                      break;
-      case GL_STENCIL_PASS_DEPTH_FAIL:                  *params = mDepthStencil.stencilPassDepthFail;             break;
-      case GL_STENCIL_PASS_DEPTH_PASS:                  *params = mDepthStencil.stencilPassDepthPass;             break;
-      case GL_STENCIL_BACK_FAIL:                        *params = mDepthStencil.stencilBackFail;                  break;
-      case GL_STENCIL_BACK_PASS_DEPTH_FAIL:             *params = mDepthStencil.stencilBackPassDepthFail;         break;
-      case GL_STENCIL_BACK_PASS_DEPTH_PASS:             *params = mDepthStencil.stencilBackPassDepthPass;         break;
-      case GL_DEPTH_FUNC:                               *params = mDepthStencil.depthFunc;                        break;
-      case GL_BLEND_SRC_RGB:                            *params = mBlend.sourceBlendRGB;                          break;
-      case GL_BLEND_SRC_ALPHA:                          *params = mBlend.sourceBlendAlpha;                        break;
-      case GL_BLEND_DST_RGB:                            *params = mBlend.destBlendRGB;                            break;
-      case GL_BLEND_DST_ALPHA:                          *params = mBlend.destBlendAlpha;                          break;
-      case GL_BLEND_EQUATION_RGB:                       *params = mBlend.blendEquationRGB;                        break;
-      case GL_BLEND_EQUATION_ALPHA:                     *params = mBlend.blendEquationAlpha;                      break;
-      case GL_STENCIL_WRITEMASK:
-          *params = CastMaskValue(context, mDepthStencil.stencilWritemask);
-          break;
-      case GL_STENCIL_BACK_WRITEMASK:
-          *params = CastMaskValue(context, mDepthStencil.stencilBackWritemask);
-          break;
-      case GL_STENCIL_CLEAR_VALUE:                      *params = mStencilClearValue;                             break;
-      case GL_IMPLEMENTATION_COLOR_READ_TYPE:
-          *params = mReadFramebuffer->getImplementationColorReadType(context);
-          break;
-      case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
-          *params = mReadFramebuffer->getImplementationColorReadFormat(context);
-          break;
-      case GL_SAMPLE_BUFFERS:
-      case GL_SAMPLES:
+        case GL_DRAW_FRAMEBUFFER_BINDING:
+            static_assert(GL_DRAW_FRAMEBUFFER_BINDING == GL_DRAW_FRAMEBUFFER_BINDING_ANGLE,
+                          "Enum mismatch");
+            *params = mDrawFramebuffer->id();
+            break;
+        case GL_READ_FRAMEBUFFER_BINDING:
+            static_assert(GL_READ_FRAMEBUFFER_BINDING == GL_READ_FRAMEBUFFER_BINDING_ANGLE,
+                          "Enum mismatch");
+            *params = mReadFramebuffer->id();
+            break;
+        case GL_RENDERBUFFER_BINDING:
+            *params = mRenderbuffer.id();
+            break;
+        case GL_VERTEX_ARRAY_BINDING:
+            *params = mVertexArray->id();
+            break;
+        case GL_CURRENT_PROGRAM:
+            *params = mProgram ? mProgram->id() : 0;
+            break;
+        case GL_PACK_ALIGNMENT:
+            *params = mPack.alignment;
+            break;
+        case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
+            *params = mPack.reverseRowOrder;
+            break;
+        case GL_PACK_ROW_LENGTH:
+            *params = mPack.rowLength;
+            break;
+        case GL_PACK_SKIP_ROWS:
+            *params = mPack.skipRows;
+            break;
+        case GL_PACK_SKIP_PIXELS:
+            *params = mPack.skipPixels;
+            break;
+        case GL_UNPACK_ALIGNMENT:
+            *params = mUnpack.alignment;
+            break;
+        case GL_UNPACK_ROW_LENGTH:
+            *params = mUnpack.rowLength;
+            break;
+        case GL_UNPACK_IMAGE_HEIGHT:
+            *params = mUnpack.imageHeight;
+            break;
+        case GL_UNPACK_SKIP_IMAGES:
+            *params = mUnpack.skipImages;
+            break;
+        case GL_UNPACK_SKIP_ROWS:
+            *params = mUnpack.skipRows;
+            break;
+        case GL_UNPACK_SKIP_PIXELS:
+            *params = mUnpack.skipPixels;
+            break;
+        case GL_GENERATE_MIPMAP_HINT:
+            *params = mGenerateMipmapHint;
+            break;
+        case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
+            *params = mFragmentShaderDerivativeHint;
+            break;
+        case GL_ACTIVE_TEXTURE:
+            *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
+            break;
+        case GL_STENCIL_FUNC:
+            *params = mDepthStencil.stencilFunc;
+            break;
+        case GL_STENCIL_REF:
+            *params = mStencilRef;
+            break;
+        case GL_STENCIL_VALUE_MASK:
+            *params = CastMaskValue(context, mDepthStencil.stencilMask);
+            break;
+        case GL_STENCIL_BACK_FUNC:
+            *params = mDepthStencil.stencilBackFunc;
+            break;
+        case GL_STENCIL_BACK_REF:
+            *params = mStencilBackRef;
+            break;
+        case GL_STENCIL_BACK_VALUE_MASK:
+            *params = CastMaskValue(context, mDepthStencil.stencilBackMask);
+            break;
+        case GL_STENCIL_FAIL:
+            *params = mDepthStencil.stencilFail;
+            break;
+        case GL_STENCIL_PASS_DEPTH_FAIL:
+            *params = mDepthStencil.stencilPassDepthFail;
+            break;
+        case GL_STENCIL_PASS_DEPTH_PASS:
+            *params = mDepthStencil.stencilPassDepthPass;
+            break;
+        case GL_STENCIL_BACK_FAIL:
+            *params = mDepthStencil.stencilBackFail;
+            break;
+        case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+            *params = mDepthStencil.stencilBackPassDepthFail;
+            break;
+        case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+            *params = mDepthStencil.stencilBackPassDepthPass;
+            break;
+        case GL_DEPTH_FUNC:
+            *params = mDepthStencil.depthFunc;
+            break;
+        case GL_BLEND_SRC_RGB:
+            *params = mBlend.sourceBlendRGB;
+            break;
+        case GL_BLEND_SRC_ALPHA:
+            *params = mBlend.sourceBlendAlpha;
+            break;
+        case GL_BLEND_DST_RGB:
+            *params = mBlend.destBlendRGB;
+            break;
+        case GL_BLEND_DST_ALPHA:
+            *params = mBlend.destBlendAlpha;
+            break;
+        case GL_BLEND_EQUATION_RGB:
+            *params = mBlend.blendEquationRGB;
+            break;
+        case GL_BLEND_EQUATION_ALPHA:
+            *params = mBlend.blendEquationAlpha;
+            break;
+        case GL_STENCIL_WRITEMASK:
+            *params = CastMaskValue(context, mDepthStencil.stencilWritemask);
+            break;
+        case GL_STENCIL_BACK_WRITEMASK:
+            *params = CastMaskValue(context, mDepthStencil.stencilBackWritemask);
+            break;
+        case GL_STENCIL_CLEAR_VALUE:
+            *params = mStencilClearValue;
+            break;
+        case GL_IMPLEMENTATION_COLOR_READ_TYPE:
+            ANGLE_TRY(mReadFramebuffer->getImplementationColorReadType(
+                context, reinterpret_cast<GLenum *>(params)));
+            break;
+        case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
+            ANGLE_TRY(mReadFramebuffer->getImplementationColorReadFormat(
+                context, reinterpret_cast<GLenum *>(params)));
+            break;
+        case GL_SAMPLE_BUFFERS:
+        case GL_SAMPLES:
         {
             Framebuffer *framebuffer = mDrawFramebuffer;
-            if (framebuffer->checkStatus(context) == GL_FRAMEBUFFER_COMPLETE)
+            bool complete            = false;
+            ANGLE_TRY(framebuffer->isComplete(context, &complete));
+            if (complete)
             {
+                GLint samples = 0;
+                ANGLE_TRY(framebuffer->getSamples(context, &samples));
                 switch (pname)
                 {
                     case GL_SAMPLE_BUFFERS:
-                        if (framebuffer->getSamples(context) != 0)
+                        if (samples != 0)
                         {
                             *params = 1;
                         }
                         else
                         {
                             *params = 0;
                         }
                         break;
                     case GL_SAMPLES:
-                        *params = framebuffer->getSamples(context);
+                        *params = samples;
                         break;
                 }
             }
             else
             {
                 *params = 0;
             }
         }
         break;
-      case GL_VIEWPORT:
-        params[0] = mViewport.x;
-        params[1] = mViewport.y;
-        params[2] = mViewport.width;
-        params[3] = mViewport.height;
-        break;
-      case GL_SCISSOR_BOX:
-        params[0] = mScissor.x;
-        params[1] = mScissor.y;
-        params[2] = mScissor.width;
-        params[3] = mScissor.height;
-        break;
-      case GL_CULL_FACE_MODE:
-          *params = ToGLenum(mRasterizer.cullMode);
-          break;
-      case GL_FRONT_FACE:
-          *params = mRasterizer.frontFace;
-          break;
-      case GL_RED_BITS:
-      case GL_GREEN_BITS:
-      case GL_BLUE_BITS:
-      case GL_ALPHA_BITS:
+        case GL_VIEWPORT:
+            params[0] = mViewport.x;
+            params[1] = mViewport.y;
+            params[2] = mViewport.width;
+            params[3] = mViewport.height;
+            break;
+        case GL_SCISSOR_BOX:
+            params[0] = mScissor.x;
+            params[1] = mScissor.y;
+            params[2] = mScissor.width;
+            params[3] = mScissor.height;
+            break;
+        case GL_CULL_FACE_MODE:
+            *params = ToGLenum(mRasterizer.cullMode);
+            break;
+        case GL_FRONT_FACE:
+            *params = mRasterizer.frontFace;
+            break;
+        case GL_RED_BITS:
+        case GL_GREEN_BITS:
+        case GL_BLUE_BITS:
+        case GL_ALPHA_BITS:
         {
             Framebuffer *framebuffer                 = getDrawFramebuffer();
             const FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
 
             if (colorbuffer)
             {
                 switch (pname)
                 {
-                case GL_RED_BITS:   *params = colorbuffer->getRedSize();      break;
-                case GL_GREEN_BITS: *params = colorbuffer->getGreenSize();    break;
-                case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();     break;
-                case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize();    break;
+                    case GL_RED_BITS:
+                        *params = colorbuffer->getRedSize();
+                        break;
+                    case GL_GREEN_BITS:
+                        *params = colorbuffer->getGreenSize();
+                        break;
+                    case GL_BLUE_BITS:
+                        *params = colorbuffer->getBlueSize();
+                        break;
+                    case GL_ALPHA_BITS:
+                        *params = colorbuffer->getAlphaSize();
+                        break;
                 }
             }
             else
             {
                 *params = 0;
             }
         }
         break;
-      case GL_DEPTH_BITS:
+        case GL_DEPTH_BITS:
         {
             const Framebuffer *framebuffer           = getDrawFramebuffer();
             const FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
 
             if (depthbuffer)
             {
                 *params = depthbuffer->getDepthSize();
             }
             else
             {
                 *params = 0;
             }
         }
         break;
-      case GL_STENCIL_BITS:
+        case GL_STENCIL_BITS:
         {
             const Framebuffer *framebuffer             = getDrawFramebuffer();
             const FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
 
             if (stencilbuffer)
             {
                 *params = stencilbuffer->getStencilSize();
             }
             else
             {
                 *params = 0;
             }
         }
         break;
-      case GL_TEXTURE_BINDING_2D:
-        ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
-        *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D);
-        break;
-      case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
-          ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
-          *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
-                                        GL_TEXTURE_RECTANGLE_ANGLE);
-          break;
-      case GL_TEXTURE_BINDING_CUBE_MAP:
-        ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
-        *params =
-            getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_CUBE_MAP);
-        break;
-      case GL_TEXTURE_BINDING_3D:
-        ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
-        *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_3D);
-        break;
-      case GL_TEXTURE_BINDING_2D_ARRAY:
-        ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
-        *params =
-            getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D_ARRAY);
-        break;
-      case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
-          ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
-          *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
-                                        GL_TEXTURE_2D_MULTISAMPLE);
-          break;
-      case GL_TEXTURE_BINDING_EXTERNAL_OES:
-          ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
-          *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
-                                        GL_TEXTURE_EXTERNAL_OES);
-          break;
-      case GL_UNIFORM_BUFFER_BINDING:
-          *params = mBoundBuffers[BufferBinding::Uniform].id();
-          break;
-      case GL_TRANSFORM_FEEDBACK_BINDING:
-        *params = mTransformFeedback.id();
-        break;
-      case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
-          ASSERT(mTransformFeedback.get() != nullptr);
-          *params = mTransformFeedback->getGenericBuffer().id();
-          break;
-      case GL_COPY_READ_BUFFER_BINDING:
-          *params = mBoundBuffers[BufferBinding::CopyRead].id();
-          break;
-      case GL_COPY_WRITE_BUFFER_BINDING:
-          *params = mBoundBuffers[BufferBinding::CopyWrite].id();
-          break;
-      case GL_PIXEL_PACK_BUFFER_BINDING:
-          *params = mBoundBuffers[BufferBinding::PixelPack].id();
-          break;
-      case GL_PIXEL_UNPACK_BUFFER_BINDING:
-          *params = mBoundBuffers[BufferBinding::PixelUnpack].id();
-          break;
-      case GL_READ_BUFFER:
-          *params = mReadFramebuffer->getReadBufferState();
-          break;
-      case GL_SAMPLER_BINDING:
-          ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
-          *params = getSamplerId(static_cast<GLuint>(mActiveSampler));
-          break;
-      case GL_DEBUG_LOGGED_MESSAGES:
-          *params = static_cast<GLint>(mDebug.getMessageCount());
-          break;
-      case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
-          *params = static_cast<GLint>(mDebug.getNextMessageLength());
-          break;
-      case GL_DEBUG_GROUP_STACK_DEPTH:
-          *params = static_cast<GLint>(mDebug.getGroupStackDepth());
-          break;
-      case GL_MULTISAMPLE_EXT:
-          *params = static_cast<GLint>(mMultiSampling);
-          break;
-      case GL_SAMPLE_ALPHA_TO_ONE_EXT:
-          *params = static_cast<GLint>(mSampleAlphaToOne);
-          break;
-      case GL_COVERAGE_MODULATION_CHROMIUM:
-          *params = static_cast<GLint>(mCoverageModulation);
-          break;
-      case GL_ATOMIC_COUNTER_BUFFER_BINDING:
-          *params = mBoundBuffers[BufferBinding::AtomicCounter].id();
-          break;
-      case GL_SHADER_STORAGE_BUFFER_BINDING:
-          *params = mBoundBuffers[BufferBinding::ShaderStorage].id();
-          break;
-      case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
-          *params = mBoundBuffers[BufferBinding::DispatchIndirect].id();
-          break;
-      default:
-        UNREACHABLE();
-        break;
+        case GL_TEXTURE_BINDING_2D:
+            ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
+            *params =
+                getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::_2D);
+            break;
+        case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
+            ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
+            *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
+                                          TextureType::Rectangle);
+            break;
+        case GL_TEXTURE_BINDING_CUBE_MAP:
+            ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
+            *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
+                                          TextureType::CubeMap);
+            break;
+        case GL_TEXTURE_BINDING_3D:
+            ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
+            *params =
+                getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::_3D);
+            break;
+        case GL_TEXTURE_BINDING_2D_ARRAY:
+            ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
+            *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
+                                          TextureType::_2DArray);
+            break;
+        case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
+            ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
+            *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
+                                          TextureType::_2DMultisample);
+            break;
+        case GL_TEXTURE_BINDING_EXTERNAL_OES:
+            ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
+            *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
+                                          TextureType::External);
+            break;
+        case GL_UNIFORM_BUFFER_BINDING:
+            *params = mBoundBuffers[BufferBinding::Uniform].id();
+            break;
+        case GL_TRANSFORM_FEEDBACK_BINDING:
+            *params = mTransformFeedback.id();
+            break;
+        case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+            *params = mBoundBuffers[BufferBinding::TransformFeedback].id();
+            break;
+        case GL_COPY_READ_BUFFER_BINDING:
+            *params = mBoundBuffers[BufferBinding::CopyRead].id();
+            break;
+        case GL_COPY_WRITE_BUFFER_BINDING:
+            *params = mBoundBuffers[BufferBinding::CopyWrite].id();
+            break;
+        case GL_PIXEL_PACK_BUFFER_BINDING:
+            *params = mBoundBuffers[BufferBinding::PixelPack].id();
+            break;
+        case GL_PIXEL_UNPACK_BUFFER_BINDING:
+            *params = mBoundBuffers[BufferBinding::PixelUnpack].id();
+            break;
+        case GL_READ_BUFFER:
+            *params = mReadFramebuffer->getReadBufferState();
+            break;
+        case GL_SAMPLER_BINDING:
+            ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
+            *params = getSamplerId(static_cast<GLuint>(mActiveSampler));
+            break;
+        case GL_DEBUG_LOGGED_MESSAGES:
+            *params = static_cast<GLint>(mDebug.getMessageCount());
+            break;
+        case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
+            *params = static_cast<GLint>(mDebug.getNextMessageLength());
+            break;
+        case GL_DEBUG_GROUP_STACK_DEPTH:
+            *params = static_cast<GLint>(mDebug.getGroupStackDepth());
+            break;
+        case GL_MULTISAMPLE_EXT:
+            *params = static_cast<GLint>(mMultiSampling);
+            break;
+        case GL_SAMPLE_ALPHA_TO_ONE_EXT:
+            *params = static_cast<GLint>(mSampleAlphaToOne);
+            break;
+        case GL_COVERAGE_MODULATION_CHROMIUM:
+            *params = static_cast<GLint>(mCoverageModulation);
+            break;
+        case GL_ATOMIC_COUNTER_BUFFER_BINDING:
+            *params = mBoundBuffers[BufferBinding::AtomicCounter].id();
+            break;
+        case GL_SHADER_STORAGE_BUFFER_BINDING:
+            *params = mBoundBuffers[BufferBinding::ShaderStorage].id();
+            break;
+        case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
+            *params = mBoundBuffers[BufferBinding::DispatchIndirect].id();
+            break;
+        case GL_ALPHA_TEST_FUNC:
+            *params = ToGLenum(mGLES1State.mAlphaTestFunc);
+            break;
+        case GL_CLIENT_ACTIVE_TEXTURE:
+            *params = mGLES1State.mClientActiveTexture + GL_TEXTURE0;
+            break;
+        case GL_MATRIX_MODE:
+            *params = ToGLenum(mGLES1State.mMatrixMode);
+            break;
+        default:
+            UNREACHABLE();
+            break;
     }
+
+    return NoError();
 }
 
 void State::getPointerv(GLenum pname, void **params) const
 {
     switch (pname)
     {
         case GL_DEBUG_CALLBACK_FUNCTION:
             *params = reinterpret_cast<void *>(mDebug.getCallback());
@@ -2086,117 +2369,117 @@ void State::getPointerv(GLenum pname, vo
             break;
     }
 }
 
 void State::getIntegeri_v(GLenum target, GLuint index, GLint *data)
 {
     switch (target)
     {
-      case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
-          ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
-          *data = mTransformFeedback->getIndexedBuffer(index).id();
-          break;
-      case GL_UNIFORM_BUFFER_BINDING:
-          ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
-          *data = mUniformBuffers[index].id();
-          break;
-      case GL_ATOMIC_COUNTER_BUFFER_BINDING:
-          ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
-          *data = mAtomicCounterBuffers[index].id();
-          break;
-      case GL_SHADER_STORAGE_BUFFER_BINDING:
-          ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
-          *data = mShaderStorageBuffers[index].id();
-          break;
-      case GL_VERTEX_BINDING_BUFFER:
-          ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
-          *data = mVertexArray->getVertexBinding(index).getBuffer().id();
-          break;
-      case GL_VERTEX_BINDING_DIVISOR:
-          ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
-          *data = mVertexArray->getVertexBinding(index).getDivisor();
-          break;
-      case GL_VERTEX_BINDING_OFFSET:
-          ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
-          *data = static_cast<GLuint>(mVertexArray->getVertexBinding(index).getOffset());
-          break;
-      case GL_VERTEX_BINDING_STRIDE:
-          ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
-          *data = mVertexArray->getVertexBinding(index).getStride();
-          break;
-      case GL_SAMPLE_MASK_VALUE:
-          ASSERT(static_cast<size_t>(index) < mSampleMaskValues.size());
-          *data = mSampleMaskValues[index];
-          break;
-      case GL_IMAGE_BINDING_NAME:
-          ASSERT(static_cast<size_t>(index) < mImageUnits.size());
-          *data = mImageUnits[index].texture.id();
-          break;
-      case GL_IMAGE_BINDING_LEVEL:
-          ASSERT(static_cast<size_t>(index) < mImageUnits.size());
-          *data = mImageUnits[index].level;
-          break;
-      case GL_IMAGE_BINDING_LAYER:
-          ASSERT(static_cast<size_t>(index) < mImageUnits.size());
-          *data = mImageUnits[index].layer;
-          break;
-      case GL_IMAGE_BINDING_ACCESS:
-          ASSERT(static_cast<size_t>(index) < mImageUnits.size());
-          *data = mImageUnits[index].access;
-          break;
-      case GL_IMAGE_BINDING_FORMAT:
-          ASSERT(static_cast<size_t>(index) < mImageUnits.size());
-          *data = mImageUnits[index].format;
-          break;
-      default:
-          UNREACHABLE();
-          break;
+        case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+            ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
+            *data = mTransformFeedback->getIndexedBuffer(index).id();
+            break;
+        case GL_UNIFORM_BUFFER_BINDING:
+            ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
+            *data = mUniformBuffers[index].id();
+            break;
+        case GL_ATOMIC_COUNTER_BUFFER_BINDING:
+            ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
+            *data = mAtomicCounterBuffers[index].id();
+            break;
+        case GL_SHADER_STORAGE_BUFFER_BINDING:
+            ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
+            *data = mShaderStorageBuffers[index].id();
+            break;
+        case GL_VERTEX_BINDING_BUFFER:
+            ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
+            *data = mVertexArray->getVertexBinding(index).getBuffer().id();
+            break;
+        case GL_VERTEX_BINDING_DIVISOR:
+            ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
+            *data = mVertexArray->getVertexBinding(index).getDivisor();
+            break;
+        case GL_VERTEX_BINDING_OFFSET:
+            ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
+            *data = static_cast<GLuint>(mVertexArray->getVertexBinding(index).getOffset());
+            break;
+        case GL_VERTEX_BINDING_STRIDE:
+            ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
+            *data = mVertexArray->getVertexBinding(index).getStride();
+            break;
+        case GL_SAMPLE_MASK_VALUE:
+            ASSERT(static_cast<size_t>(index) < mSampleMaskValues.size());
+            *data = mSampleMaskValues[index];
+            break;
+        case GL_IMAGE_BINDING_NAME:
+            ASSERT(static_cast<size_t>(index) < mImageUnits.size());
+            *data = mImageUnits[index].texture.id();
+            break;
+        case GL_IMAGE_BINDING_LEVEL:
+            ASSERT(static_cast<size_t>(index) < mImageUnits.size());
+            *data = mImageUnits[index].level;
+            break;
+        case GL_IMAGE_BINDING_LAYER:
+            ASSERT(static_cast<size_t>(index) < mImageUnits.size());
+            *data = mImageUnits[index].layer;
+            break;
+        case GL_IMAGE_BINDING_ACCESS:
+            ASSERT(static_cast<size_t>(index) < mImageUnits.size());
+            *data = mImageUnits[index].access;
+            break;
+        case GL_IMAGE_BINDING_FORMAT:
+            ASSERT(static_cast<size_t>(index) < mImageUnits.size());
+            *data = mImageUnits[index].format;
+            break;
+        default:
+            UNREACHABLE();
+            break;
     }
 }
 
 void State::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
 {
     switch (target)
     {
-      case GL_TRANSFORM_FEEDBACK_BUFFER_START:
-          ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
-          *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
-          break;
-      case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
-          ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
-          *data = mTransformFeedback->getIndexedBuffer(index).getSize();
-          break;
-      case GL_UNIFORM_BUFFER_START:
-          ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
-          *data = mUniformBuffers[index].getOffset();
-          break;
-      case GL_UNIFORM_BUFFER_SIZE:
-          ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
-          *data = mUniformBuffers[index].getSize();
-          break;
-      case GL_ATOMIC_COUNTER_BUFFER_START:
-          ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
-          *data = mAtomicCounterBuffers[index].getOffset();
-          break;
-      case GL_ATOMIC_COUNTER_BUFFER_SIZE:
-          ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
-          *data = mAtomicCounterBuffers[index].getSize();
-          break;
-      case GL_SHADER_STORAGE_BUFFER_START:
-          ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
-          *data = mShaderStorageBuffers[index].getOffset();
-          break;
-      case GL_SHADER_STORAGE_BUFFER_SIZE:
-          ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
-          *data = mShaderStorageBuffers[index].getSize();
-          break;
-      default:
-          UNREACHABLE();
-          break;
+        case GL_TRANSFORM_FEEDBACK_BUFFER_START:
+            ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
+            *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
+            break;
+        case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
+            ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
+            *data = mTransformFeedback->getIndexedBuffer(index).getSize();
+            break;
+        case GL_UNIFORM_BUFFER_START:
+            ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
+            *data = mUniformBuffers[index].getOffset();
+            break;
+        case GL_UNIFORM_BUFFER_SIZE:
+            ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
+            *data = mUniformBuffers[index].getSize();
+            break;
+        case GL_ATOMIC_COUNTER_BUFFER_START:
+            ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
+            *data = mAtomicCounterBuffers[index].getOffset();
+            break;
+        case GL_ATOMIC_COUNTER_BUFFER_SIZE:
+            ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
+            *data = mAtomicCounterBuffers[index].getSize();
+            break;
+        case GL_SHADER_STORAGE_BUFFER_START:
+            ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
+            *data = mShaderStorageBuffers[index].getOffset();
+            break;
+        case GL_SHADER_STORAGE_BUFFER_SIZE:
+            ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
+            *data = mShaderStorageBuffers[index].getSize();
+            break;
+        default:
+            UNREACHABLE();
+            break;
     }
 }
 
 void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
 {
     switch (target)
     {
         case GL_IMAGE_BINDING_LAYERED:
@@ -2209,17 +2492,17 @@ void State::getBooleani_v(GLenum target,
     }
 }
 
 bool State::hasMappedBuffer(BufferBinding target) const
 {
     if (target == BufferBinding::Array)
     {
         const VertexArray *vao     = getVertexArray();
-        const auto &vertexAttribs = vao->getVertexAttributes();
+        const auto &vertexAttribs  = vao->getVertexAttributes();
         const auto &vertexBindings = vao->getVertexBindings();
         for (size_t attribIndex : vao->getEnabledAttributesMask())
         {
             const VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
             auto *boundBuffer = vertexBindings[vertexAttrib.bindingIndex].getBuffer().get();
             if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
             {
                 return true;
@@ -2230,53 +2513,55 @@ bool State::hasMappedBuffer(BufferBindin
     }
     else
     {
         Buffer *buffer = getTargetBuffer(target);
         return (buffer && buffer->isMapped());
     }
 }
 
-void State::syncDirtyObjects(const Context *context)
+Error State::syncDirtyObjects(const Context *context)
 {
     if (!mDirtyObjects.any())
-        return;
+        return NoError();
 
-    syncDirtyObjects(context, mDirtyObjects);
+    return syncDirtyObjects(context, mDirtyObjects);
 }
 
-void State::syncDirtyObjects(const Context *context, const DirtyObjects &bitset)
+Error State::syncDirtyObjects(const Context *context, const DirtyObjects &bitset)
 {
-    for (auto dirtyObject : bitset)
+    const DirtyObjects &dirtyObjects = mDirtyObjects & bitset;
+    for (auto dirtyObject : dirtyObjects)
     {
         switch (dirtyObject)
         {
             case DIRTY_OBJECT_READ_FRAMEBUFFER:
                 ASSERT(mReadFramebuffer);
-                mReadFramebuffer->syncState(context);
+                ANGLE_TRY(mReadFramebuffer->syncState(context));
                 break;
             case DIRTY_OBJECT_DRAW_FRAMEBUFFER:
                 ASSERT(mDrawFramebuffer);
-                mDrawFramebuffer->syncState(context);
+                ANGLE_TRY(mDrawFramebuffer->syncState(context));
                 break;
             case DIRTY_OBJECT_VERTEX_ARRAY:
                 ASSERT(mVertexArray);
-                mVertexArray->syncState(context);
+                ANGLE_TRY(mVertexArray->syncState(context));
                 break;
             case DIRTY_OBJECT_PROGRAM_TEXTURES:
                 syncProgramTextures(context);
                 break;
 
             default:
                 UNREACHABLE();
                 break;
         }
     }
 
-    mDirtyObjects &= ~bitset;
+    mDirtyObjects &= ~dirtyObjects;
+    return NoError();
 }
 
 void State::syncProgramTextures(const Context *context)
 {
     // TODO(jmadill): Fine-grained updates.
     if (!mProgram)
     {
         return;
@@ -2291,17 +2576,17 @@ void State::syncProgramTextures(const Co
     // initialized.
     mCachedTexturesInitState = InitState::Initialized;
 
     for (const SamplerBinding &samplerBinding : mProgram->getSamplerBindings())
     {
         if (samplerBinding.unreferenced)
             continue;
 
-        GLenum textureType = samplerBinding.textureType;
+        TextureType textureType = samplerBinding.textureType;
         for (GLuint textureUnitIndex : samplerBinding.boundTextureUnits)
         {
             Texture *texture = getSamplerTexture(textureUnitIndex, textureType);
             Sampler *sampler = getSampler(textureUnitIndex);
             ASSERT(static_cast<size_t>(textureUnitIndex) < mCompleteTextureCache.size());
             ASSERT(static_cast<size_t>(textureUnitIndex) < newActiveTextures.size());
 
             ASSERT(texture);
@@ -2315,17 +2600,17 @@ void State::syncProgramTextures(const Co
                 mCompleteTextureCache[textureUnitIndex] = texture;
             }
             else
             {
                 mCompleteTextureCache[textureUnitIndex] = nullptr;
             }
 
             // Bind the texture unconditionally, to recieve completeness change notifications.
-            mCompleteTextureBindings[textureUnitIndex].bind(texture);
+            mCompleteTextureBindings[textureUnitIndex].bind(texture->getSubject());
             mActiveTexturesMask.set(textureUnitIndex);
             newActiveTextures.set(textureUnitIndex);
 
             if (sampler != nullptr)
             {
                 sampler->syncState(context);
             }
 
@@ -2344,17 +2629,17 @@ void State::syncProgramTextures(const Co
         {
             mCompleteTextureBindings[textureIndex].reset();
             mCompleteTextureCache[textureIndex] = nullptr;
             mActiveTexturesMask.reset(textureIndex);
         }
     }
 }
 
-void State::syncDirtyObject(const Context *context, GLenum target)
+Error State::syncDirtyObject(const Context *context, GLenum target)
 {
     DirtyObjects localSet;
 
     switch (target)
     {
         case GL_READ_FRAMEBUFFER:
             localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
             break;
@@ -2370,17 +2655,17 @@ void State::syncDirtyObject(const Contex
             break;
         case GL_TEXTURE:
         case GL_SAMPLER:
         case GL_PROGRAM:
             localSet.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
             break;
     }
 
-    syncDirtyObjects(context, localSet);
+    return syncDirtyObjects(context, localSet);
 }
 
 void State::setObjectDirty(GLenum target)
 {
     switch (target)
     {
         case GL_READ_FRAMEBUFFER:
             mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
@@ -2399,16 +2684,36 @@ void State::setObjectDirty(GLenum target
         case GL_SAMPLER:
         case GL_PROGRAM:
             mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
             mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
             break;
     }
 }
 
+void State::setFramebufferDirty(const Framebuffer *framebuffer) const
+{
+    if (framebuffer == mReadFramebuffer)
+    {
+        mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
+    }
+    if (framebuffer == mDrawFramebuffer)
+    {
+        mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
+    }
+}
+
+void State::setVertexArrayDirty(const VertexArray *vertexArray) const
+{
+    if (vertexArray == mVertexArray)
+    {
+        mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+    }
+}
+
 void State::onProgramExecutableChange(Program *program)
 {
     // OpenGL Spec:
     // "If LinkProgram or ProgramBinary successfully re-links a program object
     //  that was already in use as a result of a previous call to UseProgram, then the
     //  generated executable code will be installed as part of the current rendering state."
     if (program->isLinked() && mProgram == program)
     {
@@ -2459,16 +2764,18 @@ Error State::clearUnclearedActiveTexture
 {
     ASSERT(mRobustResourceInit);
 
     if (mCachedTexturesInitState == InitState::Initialized)
     {
         return NoError();
     }
 
+    ASSERT(!mDirtyObjects.any());
+
     for (auto textureIndex : mActiveTexturesMask)
     {
         Texture *texture = mCompleteTextureCache[textureIndex];
         if (texture)
         {
             ANGLE_TRY(texture->ensureInitialized(context));
         }
     }
@@ -2480,9 +2787,18 @@ Error State::clearUnclearedActiveTexture
 
 AttributesMask State::getAndResetDirtyCurrentValues() const
 {
     AttributesMask retVal = mDirtyCurrentValues;
     mDirtyCurrentValues.reset();
     return retVal;
 }
 
+bool State::isCurrentTransformFeedback(const TransformFeedback *tf) const
+{
+    return tf == mTransformFeedback.get();
+}
+bool State::isCurrentVertexArray(const VertexArray *va) const
+{
+    return va == mVertexArray;
+}
+
 }  // namespace gl
--- a/gfx/angle/checkout/src/libANGLE/State.h
+++ b/gfx/angle/checkout/src/libANGLE/State.h
@@ -11,16 +11,17 @@
 
 #include <bitset>
 #include <memory>
 
 #include "common/Color.h"
 #include "common/angleutils.h"
 #include "common/bitset_utils.h"
 #include "libANGLE/Debug.h"
+#include "libANGLE/GLES1State.h"
 #include "libANGLE/Program.h"
 #include "libANGLE/ProgramPipeline.h"
 #include "libANGLE/RefCountObject.h"
 #include "libANGLE/Renderbuffer.h"
 #include "libANGLE/Sampler.h"
 #include "libANGLE/Texture.h"
 #include "libANGLE/TransformFeedback.h"
 #include "libANGLE/Version.h"
@@ -169,20 +170,20 @@ class State : public angle::ObserverInte
 
     // Viewport state setter/getter
     void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
     const Rectangle &getViewport() const;
 
     // Texture binding & active texture unit manipulation
     void setActiveSampler(unsigned int active);
     unsigned int getActiveSampler() const;
-    void setSamplerTexture(const Context *context, GLenum type, Texture *texture);
-    Texture *getTargetTexture(GLenum target) const;
-    Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
-    GLuint getSamplerTextureId(unsigned int sampler, GLenum type) const;
+    void setSamplerTexture(const Context *context, TextureType type, Texture *texture);
+    Texture *getTargetTexture(TextureType type) const;
+    Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;
+    GLuint getSamplerTextureId(unsigned int sampler, TextureType type) const;
     void detachTexture(const Context *context, const TextureMap &zeroTextures, GLuint texture);
     void initializeZeroTextures(const Context *context, const TextureMap &zeroTextures);
 
     // Sampler object binding manipulation
     void setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler);
     GLuint getSamplerId(GLuint textureUnit) const;
     Sampler *getSampler(GLuint textureUnit) const;
     void detachSampler(const Context *context, GLuint sampler);
@@ -239,17 +240,17 @@ class State : public angle::ObserverInte
                                  GLintptr offset,
                                  GLsizeiptr size);
 
     const OffsetBindingPointer<Buffer> &getIndexedUniformBuffer(size_t index) const;
     const OffsetBindingPointer<Buffer> &getIndexedAtomicCounterBuffer(size_t index) const;
     const OffsetBindingPointer<Buffer> &getIndexedShaderStorageBuffer(size_t index) const;
 
     // Detach a buffer from all bindings
-    void detachBuffer(const Context *context, GLuint bufferName);
+    void detachBuffer(const Context *context, const Buffer *buffer);
 
     // Vertex attrib manipulation
     void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
     void setElementArrayBuffer(const Context *context, Buffer *buffer);
     void setVertexAttribf(GLuint index, const GLfloat values[4]);
     void setVertexAttribu(GLuint index, const GLuint values[4]);
     void setVertexAttribi(GLuint index, const GLint values[4]);
     void setVertexAttribPointer(const Context *context,
@@ -328,17 +329,17 @@ class State : public angle::ObserverInte
 
     // GL_EXT_sRGB_write_control
     void setFramebufferSRGB(bool sRGB);
     bool getFramebufferSRGB() const;
 
     // State query functions
     void getBooleanv(GLenum pname, GLboolean *params);
     void getFloatv(GLenum pname, GLfloat *params);
-    void getIntegerv(const Context *context, GLenum pname, GLint *params);
+    Error getIntegerv(const Context *context, GLenum pname, GLint *params);
     void getPointerv(GLenum pname, void **params) const;
     void getIntegeri_v(GLenum target, GLuint index, GLint *data);
     void getInteger64i_v(GLenum target, GLuint index, GLint64 *data);
     void getBooleani_v(GLenum target, GLuint index, GLboolean *data);
 
     bool hasMappedBuffer(BufferBinding target) const;
     bool isRobustResourceInitEnabled() const { return mRobustResourceInit; }
 
@@ -435,20 +436,22 @@ class State : public angle::ObserverInte
     const DirtyBits &getDirtyBits() const { return mDirtyBits; }
     void clearDirtyBits() { mDirtyBits.reset(); }
     void clearDirtyBits(const DirtyBits &bitset) { mDirtyBits &= ~bitset; }
     void setAllDirtyBits() { mDirtyBits.set(); }
 
     using DirtyObjects = angle::BitSet<DIRTY_OBJECT_MAX>;
     void clearDirtyObjects() { mDirtyObjects.reset(); }
     void setAllDirtyObjects() { mDirtyObjects.set(); }
-    void syncDirtyObjects(const Context *context);
-    void syncDirtyObjects(const Context *context, const DirtyObjects &bitset);
-    void syncDirtyObject(const Context *context, GLenum target);
+    Error syncDirtyObjects(const Context *context);
+    Error syncDirtyObjects(const Context *context, const DirtyObjects &bitset);
+    Error syncDirtyObject(const Context *context, GLenum target);
     void setObjectDirty(GLenum target);
+    void setFramebufferDirty(const Framebuffer *framebuffer) const;
+    void setVertexArrayDirty(const VertexArray *vertexArray) const;
 
     // This actually clears the current value dirty bits.
     // TODO(jmadill): Pass mutable dirty bits into Impl.
     AttributesMask getAndResetDirtyCurrentValues() const;
 
     void setImageUnit(const Context *context,
                       GLuint unit,
                       Texture *texture,
@@ -464,16 +467,22 @@ class State : public angle::ObserverInte
 
     // Observer implementation.
     void onSubjectStateChange(const Context *context,
                               angle::SubjectIndex index,
                               angle::SubjectMessage message) override;
 
     Error clearUnclearedActiveTextures(const Context *context);
 
+    bool isCurrentTransformFeedback(const TransformFeedback *tf) const;
+    bool isCurrentVertexArray(const VertexArray *va) const;
+
+    GLES1State &gles1() { return mGLES1State; }
+    const GLES1State &gles1() const { return mGLES1State; }
+
   private:
     void syncProgramTextures(const Context *context);
 
     // Cached values from Context's caps
     GLuint mMaxDrawBuffers;
     GLuint mMaxCombinedTextureImageUnits;
 
     ColorF mColorClearValue;
@@ -519,29 +528,29 @@ class State : public angle::ObserverInte
     VertexAttribVector mVertexAttribCurrentValues;  // From glVertexAttrib
     VertexArray *mVertexArray;
     ComponentTypeMask mCurrentValuesTypeMask;
 
     // Texture and sampler bindings
     size_t mActiveSampler;  // Active texture unit selector - GL_TEXTURE0
 
     typedef std::vector<BindingPointer<Texture>> TextureBindingVector;
-    typedef std::map<GLenum, TextureBindingVector> TextureBindingMap;
+    typedef angle::PackedEnumMap<TextureType, TextureBindingVector> TextureBindingMap;
     TextureBindingMap mSamplerTextures;
 
     // Texture Completeness Caching
     // ----------------------------
     // The texture completeness cache uses dirty bits to avoid having to scan the list of textures
     // each draw call. This gl::State class implements angle::Observer interface. When subject
     // Textures have state changes, messages reach 'State' (also any observing Framebuffers) via the
     // onSubjectStateChange method (above). This then invalidates the completeness cache.
     //
     // Note this requires that we also invalidate the completeness cache manually on events like
     // re-binding textures/samplers or a change in the program. For more information see the
-    // signal_utils.h header and the design doc linked there.
+    // Observer.h header and the design doc linked there.
 
     // A cache of complete textures. nullptr indicates unbound or incomplete.
     // Don't use BindingPointer because this cache is only valid within a draw call.
     // Also stores a notification channel to the texture itself to handle texture change events.
     std::vector<Texture *> mCompleteTextureCache;
     std::vector<angle::ObserverBinding> mCompleteTextureBindings;
     InitState mCachedTexturesInitState;
     using ActiveTextureMask = angle::BitSet<IMPLEMENTATION_MAX_ACTIVE_TEXTURES>;
@@ -551,33 +560,30 @@ class State : public angle::ObserverInte
     SamplerBindingVector mSamplers;
 
     typedef std::vector<ImageUnit> ImageUnitVector;
     ImageUnitVector mImageUnits;
 
     typedef std::map<GLenum, BindingPointer<Query>> ActiveQueryMap;
     ActiveQueryMap mActiveQueries;
 
-    // Stores the currently bound buffer for each binding point. It has entries for the element
-    // array buffer and the transform feedback buffer but these should not be used. Instead these
-    // bind points are respectively owned by current the vertex array object and the current
-    // transform feedback object.
+    // Stores the currently bound buffer for each binding point. It has an entry for the element
+    // array buffer but it should not be used. Instead this bind point is owned by the current
+    // vertex array object.
     using BoundBufferMap = angle::PackedEnumMap<BufferBinding, BindingPointer<Buffer>>;
     BoundBufferMap mBoundBuffers;
 
     using BufferVector = std::vector<OffsetBindingPointer<Buffer>>;
     BufferVector mUniformBuffers;
     BufferVector mAtomicCounterBuffers;
     BufferVector mShaderStorageBuffers;
 
     BindingPointer<TransformFeedback> mTransformFeedback;
 
-    BindingPointer<Buffer> mPixelUnpackBuffer;
     PixelUnpackState mUnpack;
-    BindingPointer<Buffer> mPixelPackBuffer;
     PixelPackState mPack;
 
     bool mPrimitiveRestart;
 
     Debug mDebug;
 
     bool mMultiSampling;
     bool mSampleAlphaToOne;
@@ -595,16 +601,19 @@ class State : public angle::ObserverInte
     bool mFramebufferSRGB;
 
     // GL_ANGLE_robust_resource_intialization
     bool mRobustResourceInit;
 
     // GL_ANGLE_program_cache_control
     bool mProgramBinaryCacheEnabled;
 
+    // GLES1 emulation: state specific to GLES1
+    GLES1State mGLES1State;
+
     DirtyBits mDirtyBits;
-    DirtyObjects mDirtyObjects;
+    mutable DirtyObjects mDirtyObjects;
     mutable AttributesMask mDirtyCurrentValues;
 };
 
 }  // namespace gl
 
 #endif  // LIBANGLE_STATE_H_
--- a/gfx/angle/checkout/src/libANGLE/Stream.cpp
+++ b/gfx/angle/checkout/src/libANGLE/Stream.cpp
@@ -116,34 +116,34 @@ Error Stream::createConsumerGLTextureExt
     ASSERT(mConsumerType == ConsumerType::NoConsumer);
     ASSERT(mProducerType == ProducerType::NoProducer);
     ASSERT(context != nullptr);
 
     const auto &glState = context->getGLState();
     EGLenum bufferType = attributes.getAsInt(EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER);
     if (bufferType == EGL_RGB_BUFFER)
     {
-        mPlanes[0].texture = glState.getTargetTexture(GL_TEXTURE_EXTERNAL_OES);
+        mPlanes[0].texture = glState.getTargetTexture(gl::TextureType::External);
         ASSERT(mPlanes[0].texture != nullptr);
         mPlanes[0].texture->bindStream(this);
         mConsumerType = ConsumerType::GLTextureRGB;
         mPlaneCount   = 1;
     }
     else
     {
         mPlaneCount = attributes.getAsInt(EGL_YUV_NUMBER_OF_PLANES_EXT, 2);
         ASSERT(mPlaneCount <= 3);
         for (EGLint i = 0; i < mPlaneCount; i++)
         {
             // Fetch all the textures
             mPlanes[i].textureUnit = attributes.getAsInt(EGL_YUV_PLANE0_TEXTURE_UNIT_NV + i, -1);
             if (mPlanes[i].textureUnit != EGL_NONE)
             {
                 mPlanes[i].texture =
-                    glState.getSamplerTexture(mPlanes[i].textureUnit, GL_TEXTURE_EXTERNAL_OES);
+                    glState.getSamplerTexture(mPlanes[i].textureUnit, gl::TextureType::External);
                 ASSERT(mPlanes[i].texture != nullptr);
             }
         }
 
         // Bind them to the stream
         for (EGLint i = 0; i < mPlaneCount; i++)
         {
             if (mPlanes[i].textureUnit != EGL_NONE)
--- a/gfx/angle/checkout/src/libANGLE/Surface.cpp
+++ b/gfx/angle/checkout/src/libANGLE/Surface.cpp
@@ -151,17 +151,17 @@ Error Surface::destroyImpl(const Display
     return NoError();
 }
 
 void Surface::postSwap(const gl::Context *context)
 {
     if (mRobustResourceInitialization && mSwapBehavior != EGL_BUFFER_PRESERVED)
     {
         mInitState = gl::InitState::MayNeedInit;
-        onStateChange(context, angle::SubjectMessage::STATE_CHANGE);
+        onStorageChange(context);
     }
 }
 
 Error Surface::initialize(const Display *display)
 {
     ANGLE_TRY(mImplementation->initialize(display));
 
     // Initialized here since impl is nullptr in the constructor.
--- a/gfx/angle/checkout/src/libANGLE/Texture.cpp
+++ b/gfx/angle/checkout/src/libANGLE/Texture.cpp
@@ -26,33 +26,21 @@ namespace
 {
 bool IsPointSampled(const SamplerState &samplerState)
 {
     return (samplerState.magFilter == GL_NEAREST &&
             (samplerState.minFilter == GL_NEAREST ||
              samplerState.minFilter == GL_NEAREST_MIPMAP_NEAREST));
 }
 
-size_t GetImageDescIndex(GLenum target, size_t level)
-{
-    return IsCubeMapTextureTarget(target) ? ((level * 6) + CubeMapTextureTargetToLayerIndex(target))
-                                          : level;
-}
-
-ImageIndex GetImageIndexFromDescIndex(GLenum target, size_t descIndex)
+size_t GetImageDescIndex(TextureTarget target, size_t level)
 {
-    if (target == GL_TEXTURE_CUBE_MAP)
-    {
-        size_t faceIndex = descIndex % 6;
-        size_t mipIndex  = descIndex / 6;
-        return ImageIndex::MakeCube(LayerIndexToCubeMapTextureTarget(faceIndex),
-                                    static_cast<GLint>(mipIndex));
-    }
-
-    return ImageIndex::MakeGeneric(target, static_cast<GLint>(descIndex));
+    return TextureTargetToType(target) == TextureType::CubeMap
+               ? (level * 6 + CubeMapTextureTargetToFaceIndex(target))
+               : level;
 }
 
 InitState DetermineInitState(const Context *context, const uint8_t *pixels)
 {
     // Can happen in tests.
     if (!context || !context->isRobustResourceInitEnabled())
         return InitState::Initialized;
 
@@ -78,20 +66,17 @@ bool IsMipmapFiltered(const SamplerState
             return true;
         default:
             UNREACHABLE();
             return false;
     }
 }
 
 SwizzleState::SwizzleState()
-    : swizzleRed(GL_INVALID_INDEX),
-      swizzleGreen(GL_INVALID_INDEX),
-      swizzleBlue(GL_INVALID_INDEX),
-      swizzleAlpha(GL_INVALID_INDEX)
+    : swizzleRed(GL_RED), swizzleGreen(GL_GREEN), swizzleBlue(GL_BLUE), swizzleAlpha(GL_ALPHA)
 {
 }
 
 SwizzleState::SwizzleState(GLenum red, GLenum green, GLenum blue, GLenum alpha)
     : swizzleRed(red), swizzleGreen(green), swizzleBlue(blue), swizzleAlpha(alpha)
 {
 }
 
@@ -107,28 +92,28 @@ bool SwizzleState::operator==(const Swiz
            swizzleBlue == other.swizzleBlue && swizzleAlpha == other.swizzleAlpha;
 }
 
 bool SwizzleState::operator!=(const SwizzleState &other) const
 {
     return !(*this == other);
 }
 
-TextureState::TextureState(GLenum target)
-    : mTarget(target),
-      mSwizzleState(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA),
-      mSamplerState(SamplerState::CreateDefaultForTarget(target)),
+TextureState::TextureState(TextureType type)
+    : mType(type),
+      mSamplerState(SamplerState::CreateDefaultForTarget(type)),
       mBaseLevel(0),
       mMaxLevel(1000),
       mDepthStencilTextureMode(GL_DEPTH_COMPONENT),
       mImmutableFormat(false),
       mImmutableLevels(0),
       mUsage(GL_NONE),
-      mImageDescs((IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1) *
-                  (target == GL_TEXTURE_CUBE_MAP ? 6 : 1)),
+      mImageDescs((IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1) * (type == TextureType::CubeMap ? 6 : 1)),
+      mCropRect(0, 0, 0, 0),
+      mGenerateMipmapHint(GL_FALSE),
       mInitState(InitState::MayNeedInit)
 {
 }
 
 TextureState::~TextureState()
 {
 }
 
@@ -162,19 +147,19 @@ GLuint TextureState::getEffectiveMaxLeve
     }
     return mMaxLevel;
 }
 
 GLuint TextureState::getMipmapMaxLevel() const
 {
     const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel());
     GLuint expectedMipLevels       = 0;
-    if (mTarget == GL_TEXTURE_3D)
+    if (mType == TextureType::_3D)
     {
-        const int maxDim = std::max(std::max(baseImageDesc.size.width, baseImageDesc.size.height),
+        const int maxDim  = std::max(std::max(baseImageDesc.size.width, baseImageDesc.size.height),
                                     baseImageDesc.size.depth);
         expectedMipLevels = static_cast<GLuint>(log2(maxDim));
     }
     else
     {
         expectedMipLevels = static_cast<GLuint>(
             log2(std::max(baseImageDesc.size.width, baseImageDesc.size.height)));
     }
@@ -204,39 +189,67 @@ bool TextureState::setMaxLevel(GLuint ma
 }
 
 // Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
 // According to [OpenGL ES 3.0.5] section 3.8.13 Texture Completeness page 160 any
 // per-level checks begin at the base-level.
 // For OpenGL ES2 the base level is always zero.
 bool TextureState::isCubeComplete() const
 {
-    ASSERT(mTarget == GL_TEXTURE_CUBE_MAP);
+    ASSERT(mType == TextureType::CubeMap);
 
-    const ImageDesc &baseImageDesc =
-        getImageDesc(FirstCubeMapTextureTarget, getEffectiveBaseLevel());
+    angle::EnumIterator<TextureTarget> face = kCubeMapTextureTargetMin;
+    const ImageDesc &baseImageDesc          = getImageDesc(*face, getEffectiveBaseLevel());
     if (baseImageDesc.size.width == 0 || baseImageDesc.size.width != baseImageDesc.size.height)
     {
         return false;
     }
 
-    for (GLenum face = FirstCubeMapTextureTarget + 1; face <= LastCubeMapTextureTarget; face++)
+    ++face;
+
+    for (; face != kAfterCubeMapTextureTargetMax; ++face)
     {
-        const ImageDesc &faceImageDesc = getImageDesc(face, getEffectiveBaseLevel());
+        const ImageDesc &faceImageDesc = getImageDesc(*face, getEffectiveBaseLevel());
         if (faceImageDesc.size.width != baseImageDesc.size.width ||
             faceImageDesc.size.height != baseImageDesc.size.height ||
             !Format::SameSized(faceImageDesc.format, baseImageDesc.format))
         {
             return false;
         }
     }
 
     return true;
 }
 
+const ImageDesc &TextureState::getBaseLevelDesc() const
+{
+    ASSERT(mType != TextureType::CubeMap || isCubeComplete());
+    return getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel());
+}
+
+void TextureState::setCrop(const gl::Rectangle& rect)
+{
+    mCropRect = rect;
+}
+
+const gl::Rectangle& TextureState::getCrop() const
+{
+    return mCropRect;
+}
+
+void TextureState::setGenerateMipmapHint(GLenum hint)
+{
+    mGenerateMipmapHint = hint;
+}
+
+GLenum TextureState::getGenerateMipmapHint() const
+{
+    return mGenerateMipmapHint;
+}
+
 bool TextureState::computeSamplerCompleteness(const SamplerState &samplerState,
                                               const ContextState &data) const
 {
     if (mBaseLevel > mMaxLevel)
     {
         return false;
     }
     const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel());
@@ -244,74 +257,74 @@ bool TextureState::computeSamplerComplet
         baseImageDesc.size.depth == 0)
     {
         return false;
     }
     // The cases where the texture is incomplete because base level is out of range should be
     // handled by the above condition.
     ASSERT(mBaseLevel < IMPLEMENTATION_MAX_TEXTURE_LEVELS || mImmutableFormat);
 
-    if (mTarget == GL_TEXTURE_CUBE_MAP && baseImageDesc.size.width != baseImageDesc.size.height)
+    if (mType == TextureType::CubeMap && baseImageDesc.size.width != baseImageDesc.size.height)
     {
         return false;
     }
 
     // According to es 3.1 spec, texture is justified as incomplete if sized internalformat is
     // unfilterable(table 20.11) and filter is not GL_NEAREST(8.16). The default value of minFilter
     // is NEAREST_MIPMAP_LINEAR and magFilter is LINEAR(table 20.11,). For multismaple texture,
     // filter state of multisample texture is ignored(11.1.3.3). So it shouldn't be judged as
     // incomplete texture. So, we ignore filtering for multisample texture completeness here.
-    if (mTarget != GL_TEXTURE_2D_MULTISAMPLE &&
+    if (mType != TextureType::_2DMultisample &&
         !baseImageDesc.format.info->filterSupport(data.getClientVersion(), data.getExtensions()) &&
         !IsPointSampled(samplerState))
     {
         return false;
     }
     bool npotSupport = data.getExtensions().textureNPOT || data.getClientMajorVersion() >= 3;
     if (!npotSupport)
     {
         if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !isPow2(baseImageDesc.size.width)) ||
             (samplerState.wrapT != GL_CLAMP_TO_EDGE && !isPow2(baseImageDesc.size.height)))
         {
             return false;
         }
     }
 
-    if (mTarget != GL_TEXTURE_2D_MULTISAMPLE && IsMipmapFiltered(samplerState))
+    if (mType != TextureType::_2DMultisample && IsMipmapFiltered(samplerState))
     {
         if (!npotSupport)
         {
             if (!isPow2(baseImageDesc.size.width) || !isPow2(baseImageDesc.size.height))
             {
                 return false;
             }
         }
 
         if (!computeMipmapCompleteness())
         {
             return false;
         }
     }
     else
     {
-        if (mTarget == GL_TEXTURE_CUBE_MAP && !isCubeComplete())
+        if (mType == TextureType::CubeMap && !isCubeComplete())
         {
             return false;
         }
     }
 
     // From GL_OES_EGL_image_external_essl3: If state is present in a sampler object bound to a
     // texture unit that would have been rejected by a call to TexParameter* for the texture bound
     // to that unit, the behavior of the implementation is as if the texture were incomplete. For
     // example, if TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to anything but CLAMP_TO_EDGE on the
     // sampler object bound to a texture unit and the texture bound to that unit is an external
     // texture, the texture will be considered incomplete.
     // Sampler object state which does not affect sampling for the type of texture bound to a
     // texture unit, such as TEXTURE_WRAP_R for an external texture, does not affect completeness.
-    if (mTarget == GL_TEXTURE_EXTERNAL_OES)
+    if (mType == TextureType::External)
     {
         if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE)
         {
             return false;
         }
 
         if (samplerState.minFilter != GL_LINEAR && samplerState.minFilter != GL_NEAREST)
         {
@@ -319,17 +332,17 @@ bool TextureState::computeSamplerComplet
         }
     }
 
     // OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if:
     // The internalformat specified for the texture arrays is a sized internal depth or
     // depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_-
     // MODE is NONE, and either the magnification filter is not NEAREST or the mini-
     // fication filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST.
-    if (mTarget != GL_TEXTURE_2D_MULTISAMPLE && baseImageDesc.format.info->depthBits > 0 &&
+    if (mType != TextureType::_2DMultisample && baseImageDesc.format.info->depthBits > 0 &&
         data.getClientMajorVersion() >= 3)
     {
         // Note: we restrict this validation to sized types. For the OES_depth_textures
         // extension, due to some underspecification problems, we must allow linear filtering
         // for legacy compatibility with WebGL 1.
         // See http://crbug.com/649200
         if (samplerState.compareMode == GL_NONE && baseImageDesc.format.info->sized)
         {
@@ -346,17 +359,17 @@ bool TextureState::computeSamplerComplet
     // The internalformat specified for the texture is DEPTH_STENCIL format, the value of
     // DEPTH_STENCIL_TEXTURE_MODE is STENCIL_INDEX, and either the magnification filter is
     // not NEAREST or the minification filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST.
     // However, the ES 3.1 spec differs from the statement above, because it is incorrect.
     // See the issue at https://github.com/KhronosGroup/OpenGL-API/issues/33.
     // For multismaple texture, filter state of multisample texture is ignored(11.1.3.3).
     // So it shouldn't be judged as incomplete texture. So, we ignore filtering for multisample
     // texture completeness here.
-    if (mTarget != GL_TEXTURE_2D_MULTISAMPLE && baseImageDesc.format.info->depthBits > 0 &&
+    if (mType != TextureType::_2DMultisample && baseImageDesc.format.info->depthBits > 0 &&
         mDepthStencilTextureMode == GL_STENCIL_INDEX)
     {
         if ((samplerState.minFilter != GL_NEAREST &&
              samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) ||
             samplerState.magFilter != GL_NEAREST)
         {
             return false;
         }
@@ -366,39 +379,39 @@ bool TextureState::computeSamplerComplet
 }
 
 bool TextureState::computeMipmapCompleteness() const
 {
     const GLuint maxLevel = getMipmapMaxLevel();
 
     for (GLuint level = getEffectiveBaseLevel(); level <= maxLevel; level++)
     {
-        if (mTarget == GL_TEXTURE_CUBE_MAP)
+        if (mType == TextureType::CubeMap)
         {
-            for (GLenum face = FirstCubeMapTextureTarget; face <= LastCubeMapTextureTarget; face++)
+            for (TextureTarget face : AllCubeFaceTextureTargets())
             {
                 if (!computeLevelCompleteness(face, level))
                 {
                     return false;
                 }
             }
         }
         else
         {
-            if (!computeLevelCompleteness(mTarget, level))
+            if (!computeLevelCompleteness(NonCubeTextureTypeToTarget(mType), level))
             {
                 return false;
             }
         }
     }
 
     return true;
 }
 
-bool TextureState::computeLevelCompleteness(GLenum target, size_t level) const
+bool TextureState::computeLevelCompleteness(TextureTarget target, size_t level) const
 {
     ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
 
     if (mImmutableFormat)
     {
         return true;
     }
 
@@ -428,37 +441,38 @@ bool TextureState::computeLevelCompleten
         return false;
     }
 
     if (levelImageDesc.size.height != std::max(1, baseImageDesc.size.height >> relativeLevel))
     {
         return false;
     }
 
-    if (mTarget == GL_TEXTURE_3D)
+    if (mType == TextureType::_3D)
     {
         if (levelImageDesc.size.depth != std::max(1, baseImageDesc.size.depth >> relativeLevel))
         {
             return false;
         }
     }
-    else if (mTarget == GL_TEXTURE_2D_ARRAY)
+    else if (mType == TextureType::_2DArray)
     {
         if (levelImageDesc.size.depth != baseImageDesc.size.depth)
         {
             return false;
         }
     }
 
     return true;
 }
 
-GLenum TextureState::getBaseImageTarget() const
+TextureTarget TextureState::getBaseImageTarget() const
 {
-    return mTarget == GL_TEXTURE_CUBE_MAP ? FirstCubeMapTextureTarget : mTarget;
+    return mType == TextureType::CubeMap ? kCubeMapTextureTargetMin
+                                         : NonCubeTextureTypeToTarget(mType);
 }
 
 ImageDesc::ImageDesc()
     : ImageDesc(Extents(0, 0, 0), Format::Invalid(), 0, GL_TRUE, InitState::Initialized)
 {
 }
 
 ImageDesc::ImageDesc(const Extents &size, const Format &format, const InitState initState)
@@ -474,24 +488,24 @@ ImageDesc::ImageDesc(const Extents &size
     : size(size),
       format(format),
       samples(samples),
       fixedSampleLocations(fixedSampleLocations),
       initState(initState)
 {
 }
 
-const ImageDesc &TextureState::getImageDesc(GLenum target, size_t level) const
+const ImageDesc &TextureState::getImageDesc(TextureTarget target, size_t level) const
 {
     size_t descIndex = GetImageDescIndex(target, level);
     ASSERT(descIndex < mImageDescs.size());
     return mImageDescs[descIndex];
 }
 
-void TextureState::setImageDesc(GLenum target, size_t level, const ImageDesc &desc)
+void TextureState::setImageDesc(TextureTarget target, size_t level, const ImageDesc &desc)
 {
     size_t descIndex = GetImageDescIndex(target, level);
     ASSERT(descIndex < mImageDescs.size());
     mImageDescs[descIndex] = desc;
     if (desc.initState == InitState::MayNeedInit)
     {
         mInitState = InitState::MayNeedInit;
     }
@@ -508,62 +522,62 @@ void TextureState::setImageDescChain(GLu
                                      const Format &format,
                                      InitState initState)
 {
     for (GLuint level = baseLevel; level <= maxLevel; level++)
     {
         int relativeLevel = (level - baseLevel);
         Extents levelSize(std::max<int>(baseSize.width >> relativeLevel, 1),
                           std::max<int>(baseSize.height >> relativeLevel, 1),
-                          (mTarget == GL_TEXTURE_2D_ARRAY)
+                          (mType == TextureType::_2DArray)
                               ? baseSize.depth
                               : std::max<int>(baseSize.depth >> relativeLevel, 1));
         ImageDesc levelInfo(levelSize, format, initState);
 
-        if (mTarget == GL_TEXTURE_CUBE_MAP)
+        if (mType == TextureType::CubeMap)
         {
-            for (GLenum face = FirstCubeMapTextureTarget; face <= LastCubeMapTextureTarget; face++)
+            for (TextureTarget face : AllCubeFaceTextureTargets())
             {
                 setImageDesc(face, level, levelInfo);
             }
         }
         else
         {
-            setImageDesc(mTarget, level, levelInfo);
+            setImageDesc(NonCubeTextureTypeToTarget(mType), level, levelInfo);
         }
     }
 }
 
 void TextureState::setImageDescChainMultisample(Extents baseSize,
                                                 const Format &format,
                                                 GLsizei samples,
                                                 bool fixedSampleLocations,
                                                 InitState initState)
 {
-    ASSERT(mTarget == GL_TEXTURE_2D_MULTISAMPLE);
+    ASSERT(mType == TextureType::_2DMultisample);
     ImageDesc levelInfo(baseSize, format, samples, fixedSampleLocations, initState);
-    setImageDesc(mTarget, 0, levelInfo);
+    setImageDesc(TextureTarget::_2DMultisample, 0, levelInfo);
 }
 
-void TextureState::clearImageDesc(GLenum target, size_t level)
+void TextureState::clearImageDesc(TextureTarget target, size_t level)
 {
     setImageDesc(target, level, ImageDesc());
 }
 
 void TextureState::clearImageDescs()
 {
     for (size_t descIndex = 0; descIndex < mImageDescs.size(); descIndex++)
     {
         mImageDescs[descIndex] = ImageDesc();
     }
 }
 
-Texture::Texture(rx::GLImplFactory *factory, GLuint id, GLenum target)
+Texture::Texture(rx::GLImplFactory *factory, GLuint id, TextureType type)
     : egl::ImageSibling(id),
-      mState(target),
+      mState(type),
       mTexture(factory->createTexture(mState)),
       mLabel(),
       mBoundSurface(nullptr),
       mBoundStream(nullptr)
 {
 }
 
 Error Texture::onDestroy(const Context *context)
@@ -599,19 +613,19 @@ void Texture::setLabel(const std::string
     mDirtyBits.set(DIRTY_BIT_LABEL);
 }
 
 const std::string &Texture::getLabel() const
 {
     return mLabel;
 }
 
-GLenum Texture::getTarget() const
+TextureType Texture::getType() const
 {
-    return mState.mTarget;
+    return mState.mType;
 }
 
 void Texture::setSwizzleRed(GLenum swizzleRed)
 {
     mState.mSwizzleState.swizzleRed = swizzleRed;
     mDirtyBits.set(DIRTY_BIT_SWIZZLE_RED);
 }
 
@@ -846,55 +860,49 @@ GLenum Texture::getUsage() const
     return mState.mUsage;
 }
 
 const TextureState &Texture::getTextureState() const
 {
     return mState;
 }
 
-size_t Texture::getWidth(GLenum target, size_t level) const
+size_t Texture::getWidth(TextureTarget target, size_t level) const
 {
-    ASSERT(target == mState.mTarget ||
-           (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+    ASSERT(TextureTargetToType(target) == mState.mType);
     return mState.getImageDesc(target, level).size.width;
 }
 
-size_t Texture::getHeight(GLenum target, size_t level) const
+size_t Texture::getHeight(TextureTarget target, size_t level) const
 {
-    ASSERT(target == mState.mTarget ||
-           (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+    ASSERT(TextureTargetToType(target) == mState.mType);
     return mState.getImageDesc(target, level).size.height;
 }
 
-size_t Texture::getDepth(GLenum target, size_t level) const
+size_t Texture::getDepth(TextureTarget target, size_t level) const
 {
-    ASSERT(target == mState.mTarget ||
-           (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+    ASSERT(TextureTargetToType(target) == mState.mType);
     return mState.getImageDesc(target, level).size.depth;
 }
 
-const Format &Texture::getFormat(GLenum target, size_t level) const
+const Format &Texture::getFormat(TextureTarget target, size_t level) const
 {
-    ASSERT(target == mState.mTarget ||
-           (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+    ASSERT(TextureTargetToType(target) == mState.mType);
     return mState.getImageDesc(target, level).format;
 }
 
-GLsizei Texture::getSamples(GLenum target, size_t level) const
+GLsizei Texture::getSamples(TextureTarget target, size_t level) const
 {
-    ASSERT(target == mState.mTarget ||
-           (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+    ASSERT(TextureTargetToType(target) == mState.mType);
     return mState.getImageDesc(target, level).samples;
 }
 
-bool Texture::getFixedSampleLocations(GLenum target, size_t level) const
+bool Texture::getFixedSampleLocations(TextureTarget target, size_t level) const
 {
-    ASSERT(target == mState.mTarget ||
-           (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+    ASSERT(TextureTargetToType(target) == mState.mType);
     return mState.getImageDesc(target, level).fixedSampleLocations;
 }
 
 GLuint Texture::getMipmapMaxLevel() const
 {
     return mState.getMipmapMaxLevel();
 }
 
@@ -911,253 +919,263 @@ egl::Surface *Texture::getBoundSurface()
 egl::Stream *Texture::getBoundStream() const
 {
     return mBoundStream;
 }
 
 void Texture::signalDirty(const Context *context, InitState initState)
 {
     mState.mInitState = initState;
-    onStateChange(context, angle::SubjectMessage::STATE_CHANGE);
+    onStorageChange(context);
     invalidateCompletenessCache();
 }
 
 Error Texture::setImage(const Context *context,
                         const PixelUnpackState &unpackState,
-                        GLenum target,
-                        size_t level,
+                        TextureTarget target,
+                        GLint level,
                         GLenum internalFormat,
                         const Extents &size,
                         GLenum format,
                         GLenum type,
                         const uint8_t *pixels)
 {
-    ASSERT(target == mState.mTarget ||
-           (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+    ASSERT(TextureTargetToType(target) == mState.mType);
 
     // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
     ANGLE_TRY(releaseTexImageInternal(context));
     ANGLE_TRY(orphanImages(context));
 
-    ANGLE_TRY(mTexture->setImage(context, target, level, internalFormat, size, format, type,
-                                 unpackState, pixels));
+    ImageIndex index = ImageIndex::MakeGeneric(target, level);
+
+    ANGLE_TRY(mTexture->setImage(context, index, internalFormat, size, format, type, unpackState,
+                                 pixels));
 
     InitState initState = DetermineInitState(context, pixels);
     mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat, type), initState));
     signalDirty(context, initState);
 
     return NoError();
 }
 
 Error Texture::setSubImage(const Context *context,
                            const PixelUnpackState &unpackState,
-                           GLenum target,
-                           size_t level,
+                           TextureTarget target,
+                           GLint level,
                            const Box &area,
                            GLenum format,
                            GLenum type,
                            const uint8_t *pixels)
 {
-    ASSERT(target == mState.mTarget ||
-           (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+    ASSERT(TextureTargetToType(target) == mState.mType);
 
     ANGLE_TRY(ensureSubImageInitialized(context, target, level, area));
 
-    return mTexture->setSubImage(context, target, level, area, format, type, unpackState, pixels);
+    ImageIndex index = ImageIndex::MakeGeneric(target, level);
+
+    return mTexture->setSubImage(context, index, area, format, type, unpackState, pixels);
 }
 
 Error Texture::setCompressedImage(const Context *context,
                                   const PixelUnpackState &unpackState,
-                                  GLenum target,
-                                  size_t level,
+                                  TextureTarget target,
+                                  GLint level,
                                   GLenum internalFormat,
                                   const Extents &size,
                                   size_t imageSize,
                                   const uint8_t *pixels)
 {
-    ASSERT(target == mState.mTarget ||
-           (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+    ASSERT(TextureTargetToType(target) == mState.mType);
 
     // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
     ANGLE_TRY(releaseTexImageInternal(context));
     ANGLE_TRY(orphanImages(context));
 
-    ANGLE_TRY(mTexture->setCompressedImage(context, target, level, internalFormat, size,
-                                           unpackState, imageSize, pixels));
+    ImageIndex index = ImageIndex::MakeGeneric(target, level);
+
+    ANGLE_TRY(mTexture->setCompressedImage(context, index, internalFormat, size, unpackState,
+                                           imageSize, pixels));
 
     InitState initState = DetermineInitState(context, pixels);
     mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat), initState));
     signalDirty(context, initState);
 
     return NoError();
 }
 
 Error Texture::setCompressedSubImage(const Context *context,
                                      const PixelUnpackState &unpackState,
-                                     GLenum target,
-                                     size_t level,
+                                     TextureTarget target,
+                                     GLint level,
                                      const Box &area,
                                      GLenum format,
                                      size_t imageSize,
                                      const uint8_t *pixels)
 {
-    ASSERT(target == mState.mTarget ||
-           (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+    ASSERT(TextureTargetToType(target) == mState.mType);
 
     ANGLE_TRY(ensureSubImageInitialized(context, target, level, area));
 
-    return mTexture->setCompressedSubImage(context, target, level, area, format, unpackState,
-                                           imageSize, pixels);
+    ImageIndex index = ImageIndex::MakeGeneric(target, level);
+
+    return mTexture->setCompressedSubImage(context, index, area, format, unpackState, imageSize,
+                                           pixels);
 }
 
 Error Texture::copyImage(const Context *context,
-                         GLenum target,
-                         size_t level,
+                         TextureTarget target,
+                         GLint level,
                          const Rectangle &sourceArea,
                          GLenum internalFormat,
                          Framebuffer *source)
 {
-    ASSERT(target == mState.mTarget ||
-           (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+    ASSERT(TextureTargetToType(target) == mState.mType);
 
     // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
     ANGLE_TRY(releaseTexImageInternal(context));
     ANGLE_TRY(orphanImages(context));
 
     // Ensure source FBO is initialized.
     ANGLE_TRY(source->ensureReadAttachmentInitialized(context, GL_COLOR_BUFFER_BIT));
 
     // Use the source FBO size as the init image area.
     Box destBox(0, 0, 0, sourceArea.width, sourceArea.height, 1);
     ANGLE_TRY(ensureSubImageInitialized(context, target, level, destBox));
 
-    ANGLE_TRY(mTexture->copyImage(context, target, level, sourceArea, internalFormat, source));
+    ImageIndex index = ImageIndex::MakeGeneric(target, level);
+
+    ANGLE_TRY(mTexture->copyImage(context, index, sourceArea, internalFormat, source));
 
     const InternalFormat &internalFormatInfo =
         GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE);
 
     mState.setImageDesc(target, level,
                         ImageDesc(Extents(sourceArea.width, sourceArea.height, 1),
                                   Format(internalFormatInfo), InitState::Initialized));
 
     // We need to initialize this texture only if the source attachment is not initialized.
     signalDirty(context, InitState::Initialized);
 
     return NoError();
 }
 
 Error Texture::copySubImage(const Context *context,
-                            GLenum target,
-                            size_t level,
+                            TextureTarget target,
+                            GLint level,
                             const Offset &destOffset,
                             const Rectangle &sourceArea,
                             Framebuffer *source)
 {
-    ASSERT(target == mState.mTarget ||
-           (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+    ASSERT(TextureTargetToType(target) == mState.mType);
 
     // Ensure source FBO is initialized.
     ANGLE_TRY(source->ensureReadAttachmentInitialized(context, GL_COLOR_BUFFER_BIT));
 
     Box destBox(destOffset.x, destOffset.y, destOffset.y, sourceArea.width, sourceArea.height, 1);
     ANGLE_TRY(ensureSubImageInitialized(context, target, level, destBox));
 
-    return mTexture->copySubImage(context, target, level, destOffset, sourceArea, source);
+    ImageIndex index = ImageIndex::MakeGeneric(target, level);
+
+    return mTexture->copySubImage(context, index, destOffset, sourceArea, source);
 }
 
 Error Texture::copyTexture(const Context *context,
-                           GLenum target,
-                           size_t level,
+                           TextureTarget target,
+                           GLint level,
                            GLenum internalFormat,
                            GLenum type,
-                           size_t sourceLevel,
+                           GLint sourceLevel,
                            bool unpackFlipY,
                            bool unpackPremultiplyAlpha,
                            bool unpackUnmultiplyAlpha,
                            Texture *source)
 {
-    ASSERT(target == mState.mTarget ||
-           (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+    ASSERT(TextureTargetToType(target) == mState.mType);
+    ASSERT(source->getType() != TextureType::CubeMap);
 
     // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
     ANGLE_TRY(releaseTexImageInternal(context));
     ANGLE_TRY(orphanImages(context));
 
     // Initialize source texture.
     // Note: we don't have a way to notify which portions of the image changed currently.
     ANGLE_TRY(source->ensureInitialized(context));
 
-    ANGLE_TRY(mTexture->copyTexture(context, target, level, internalFormat, type, sourceLevel,
-                                    unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha,
-                                    source));
+    ImageIndex index = ImageIndex::MakeGeneric(target, level);
 
-    const auto &sourceDesc   = source->mState.getImageDesc(source->getTarget(), 0);
+    ANGLE_TRY(mTexture->copyTexture(context, index, internalFormat, type, sourceLevel, unpackFlipY,
+                                    unpackPremultiplyAlpha, unpackUnmultiplyAlpha, source));
+
+    const auto &sourceDesc =
+        source->mState.getImageDesc(NonCubeTextureTypeToTarget(source->getType()), 0);
     const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
     mState.setImageDesc(
         target, level,
         ImageDesc(sourceDesc.size, Format(internalFormatInfo), InitState::Initialized));
 
     signalDirty(context, InitState::Initialized);
 
     return NoError();
 }
 
 Error Texture::copySubTexture(const Context *context,
-                              GLenum target,
-                              size_t level,
+                              TextureTarget target,
+                              GLint level,
                               const Offset &destOffset,
-                              size_t sourceLevel,
+                              GLint sourceLevel,
                               const Rectangle &sourceArea,
                               bool unpackFlipY,
                               bool unpackPremultiplyAlpha,
                               bool unpackUnmultiplyAlpha,
                               Texture *source)
 {
-    ASSERT(target == mState.mTarget ||
-           (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+    ASSERT(TextureTargetToType(target) == mState.mType);
 
     // Ensure source is initialized.
     ANGLE_TRY(source->ensureInitialized(context));
 
     Box destBox(destOffset.x, destOffset.y, destOffset.y, sourceArea.width, sourceArea.height, 1);
     ANGLE_TRY(ensureSubImageInitialized(context, target, level, destBox));
 
-    return mTexture->copySubTexture(context, target, level, destOffset, sourceLevel, sourceArea,
+    ImageIndex index = ImageIndex::MakeGeneric(target, level);
+
+    return mTexture->copySubTexture(context, index, destOffset, sourceLevel, sourceArea,
                                     unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha,
                                     source);
 }
 
 Error Texture::copyCompressedTexture(const Context *context, const Texture *source)
 {
     // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
     ANGLE_TRY(releaseTexImageInternal(context));
     ANGLE_TRY(orphanImages(context));
 
     ANGLE_TRY(mTexture->copyCompressedTexture(context, source));
 
-    ASSERT(source->getTarget() != GL_TEXTURE_CUBE_MAP && getTarget() != GL_TEXTURE_CUBE_MAP);
-    const auto &sourceDesc = source->mState.getImageDesc(source->getTarget(), 0);
-    mState.setImageDesc(getTarget(), 0, sourceDesc);
+    ASSERT(source->getType() != TextureType::CubeMap && getType() != TextureType::CubeMap);
+    const auto &sourceDesc =
+        source->mState.getImageDesc(NonCubeTextureTypeToTarget(source->getType()), 0);
+    mState.setImageDesc(NonCubeTextureTypeToTarget(getType()), 0, sourceDesc);
 
     return NoError();
 }
 
 Error Texture::setStorage(const Context *context,
-                          GLenum target,
+                          TextureType type,
                           GLsizei levels,
                           GLenum internalFormat,
                           const Extents &size)
 {
-    ASSERT(target == mState.mTarget);
+    ASSERT(type == mState.mType);
 
     // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
     ANGLE_TRY(releaseTexImageInternal(context));
     ANGLE_TRY(orphanImages(context));
 
-    ANGLE_TRY(mTexture->setStorage(context, target, levels, internalFormat, size));
+    ANGLE_TRY(mTexture->setStorage(context, type, levels, internalFormat, size));
 
     mState.mImmutableFormat = true;
     mState.mImmutableLevels = static_cast<GLuint>(levels);
     mState.clearImageDescs();
     mState.setImageDescChain(0, static_cast<GLuint>(levels - 1), size, Format(internalFormat),
                              InitState::MayNeedInit);
 
     // Changing the texture to immutable can trigger a change in the base and max levels:
@@ -1168,29 +1186,29 @@ Error Texture::setStorage(const Context 
     mDirtyBits.set(DIRTY_BIT_MAX_LEVEL);
 
     signalDirty(context, InitState::MayNeedInit);
 
     return NoError();
 }
 
 Error Texture::setStorageMultisample(const Context *context,
-                                     GLenum target,
+                                     TextureType type,
                                      GLsizei samples,
                                      GLint internalFormat,
                                      const Extents &size,
                                      bool fixedSampleLocations)
 {
-    ASSERT(target == mState.mTarget);
+    ASSERT(type == mState.mType);
 
     // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
     ANGLE_TRY(releaseTexImageInternal(context));
     ANGLE_TRY(orphanImages(context));
 
-    ANGLE_TRY(mTexture->setStorageMultisample(context, target, samples, internalFormat, size,
+    ANGLE_TRY(mTexture->setStorageMultisample(context, type, samples, internalFormat, size,
                                               fixedSampleLocations));
 
     mState.mImmutableFormat = true;
     mState.mImmutableLevels = static_cast<GLuint>(1);
     mState.clearImageDescs();
     mState.setImageDescChainMultisample(size, Format(internalFormat), samples, fixedSampleLocations,
                                         InitState::MayNeedInit);
 
@@ -1209,35 +1227,46 @@ Error Texture::generateMipmap(const Cont
     if (!isMipmapComplete())
     {
         ANGLE_TRY(orphanImages(context));
     }
 
     const GLuint baseLevel = mState.getEffectiveBaseLevel();
     const GLuint maxLevel  = mState.getMipmapMaxLevel();
 
-    if (maxLevel > baseLevel)
+    if (maxLevel <= baseLevel)
     {
-        syncState();
-        const ImageDesc &baseImageInfo =
-            mState.getImageDesc(mState.getBaseImageTarget(), baseLevel);
+        return NoError();
+    }
+    syncState();
 
-        // Clear the base image immediately if necessary.
-        if (context->isRobustResourceInitEnabled() &&
-            baseImageInfo.initState == InitState::MayNeedInit)
+    // Clear the base image(s) immediately if needed
+    if (context->isRobustResourceInitEnabled())
+    {
+        ImageIndexIterator it =
+            ImageIndexIterator::MakeGeneric(mState.mType, baseLevel, baseLevel + 1);
+        while (it.hasNext())
         {
-            ANGLE_TRY(initializeContents(
-                context, GetImageIndexFromDescIndex(mState.getBaseImageTarget(), baseLevel)));
-        }
+            const ImageIndex index = it.next();
+            const ImageDesc &desc  = mState.getImageDesc(index.target, index.mipIndex);
 
-        ANGLE_TRY(mTexture->generateMipmap(context));
+            if (desc.initState == InitState::MayNeedInit)
+            {
+                ANGLE_TRY(initializeContents(context, index));
+            }
+        }
+    }
 
-        mState.setImageDescChain(baseLevel, maxLevel, baseImageInfo.size, baseImageInfo.format,
-                                 InitState::Initialized);
-    }
+    ANGLE_TRY(mTexture->generateMipmap(context));
+
+    // Propagate the format and size of the bsae mip to the smaller ones. Cube maps are guaranteed
+    // to have faces of the same size and format so any faces can be picked.
+    const ImageDesc &baseImageInfo = mState.getImageDesc(mState.getBaseImageTarget(), baseLevel);
+    mState.setImageDescChain(baseLevel, maxLevel, baseImageInfo.size, baseImageInfo.format,
+                             InitState::Initialized);
 
     signalDirty(context, InitState::Initialized);
 
     return NoError();
 }
 
 Error Texture::bindTexImageFromSurface(const Context *context, egl::Surface *surface)
 {
@@ -1247,76 +1276,76 @@ Error Texture::bindTexImageFromSurface(c
     {
         ANGLE_TRY(releaseTexImageFromSurface(context));
     }
 
     ANGLE_TRY(mTexture->bindTexImage(context, surface));
     mBoundSurface = surface;
 
     // Set the image info to the size and format of the surface
-    ASSERT(mState.mTarget == GL_TEXTURE_2D || mState.mTarget == GL_TEXTURE_RECTANGLE_ANGLE);
+    ASSERT(mState.mType == TextureType::_2D || mState.mType == TextureType::Rectangle);
     Extents size(surface->getWidth(), surface->getHeight(), 1);
     ImageDesc desc(size, surface->getBindTexImageFormat(), InitState::Initialized);
-    mState.setImageDesc(mState.mTarget, 0, desc);
+    mState.setImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0, desc);
     signalDirty(context, InitState::Initialized);
     return NoError();
 }
 
 Error Texture::releaseTexImageFromSurface(const Context *context)
 {
     ASSERT(mBoundSurface);
     mBoundSurface = nullptr;
     ANGLE_TRY(mTexture->releaseTexImage(context));
 
     // Erase the image info for level 0
-    ASSERT(mState.mTarget == GL_TEXTURE_2D || mState.mTarget == GL_TEXTURE_RECTANGLE_ANGLE);
-    mState.clearImageDesc(mState.mTarget, 0);
+    ASSERT(mState.mType == TextureType::_2D || mState.mType == TextureType::Rectangle);
+    mState.clearImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0);
     signalDirty(context, InitState::Initialized);
     return NoError();
 }
 
 void Texture::bindStream(egl::Stream *stream)
 {
     ASSERT(stream);
 
     // It should not be possible to bind a texture already bound to another stream
     ASSERT(mBoundStream == nullptr);
 
     mBoundStream = stream;
 
-    ASSERT(mState.mTarget == GL_TEXTURE_EXTERNAL_OES);
+    ASSERT(mState.mType == TextureType::External);
 }
 
 void Texture::releaseStream()
 {
     ASSERT(mBoundStream);
     mBoundStream = nullptr;
 }
 
 Error Texture::acquireImageFromStream(const Context *context,
                                       const egl::Stream::GLTextureDescription &desc)
 {
     ASSERT(mBoundStream != nullptr);
-    ANGLE_TRY(mTexture->setImageExternal(context, mState.mTarget, mBoundStream, desc));
+    ANGLE_TRY(mTexture->setImageExternal(context, mState.mType, mBoundStream, desc));
 
     Extents size(desc.width, desc.height, 1);
-    mState.setImageDesc(mState.mTarget, 0,
+    mState.setImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0,
                         ImageDesc(size, Format(desc.internalFormat), InitState::Initialized));
     signalDirty(context, InitState::Initialized);
     return NoError();
 }
 
 Error Texture::releaseImageFromStream(const Context *context)
 {
     ASSERT(mBoundStream != nullptr);
-    ANGLE_TRY(mTexture->setImageExternal(context, mState.mTarget, nullptr,
+    ANGLE_TRY(mTexture->setImageExternal(context, mState.mType, nullptr,
                                          egl::Stream::GLTextureDescription()));
 
     // Set to incomplete
-    mState.clearImageDesc(mState.mTarget, 0);
+    mState.clearImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0);
     signalDirty(context, InitState::Initialized);
     return NoError();
 }
 
 Error Texture::releaseTexImageInternal(const Context *context)
 {
     if (mBoundSurface)
     {
@@ -1324,36 +1353,37 @@ Error Texture::releaseTexImageInternal(c
         mBoundSurface->releaseTexImageFromTexture(context);
 
         // Then, call the same method as from the surface
         ANGLE_TRY(releaseTexImageFromSurface(context));
     }
     return NoError();
 }
 
-Error Texture::setEGLImageTarget(const Context *context, GLenum target, egl::Image *imageTarget)
+Error Texture::setEGLImageTarget(const Context *context, TextureType type, egl::Image *imageTarget)
 {
-    ASSERT(target == mState.mTarget);
-    ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES);
+    ASSERT(type == mState.mType);
+    ASSERT(type == TextureType::_2D || type == TextureType::External);
 
     // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
     ANGLE_TRY(releaseTexImageInternal(context));
     ANGLE_TRY(orphanImages(context));
 
-    ANGLE_TRY(mTexture->setEGLImageTarget(context, target, imageTarget));
+    ANGLE_TRY(mTexture->setEGLImageTarget(context, type, imageTarget));
 
     setTargetImage(context, imageTarget);
 
     Extents size(static_cast<int>(imageTarget->getWidth()),
                  static_cast<int>(imageTarget->getHeight()), 1);
 
     auto initState = imageTarget->sourceInitState();
 
     mState.clearImageDescs();
-    mState.setImageDesc(target, 0, ImageDesc(size, imageTarget->getFormat(), initState));
+    mState.setImageDesc(NonCubeTextureTypeToTarget(type), 0,
+                        ImageDesc(size, imageTarget->getFormat(), initState));
     signalDirty(context, initState);
 
     return NoError();
 }
 
 Extents Texture::getAttachmentSize(const ImageIndex &imageIndex) const
 {
     return mState.getImageDesc(imageIndex).size;
@@ -1364,16 +1394,36 @@ const Format &Texture::getAttachmentForm
     return mState.getImageDesc(imageIndex).format;
 }
 
 GLsizei Texture::getAttachmentSamples(const ImageIndex &imageIndex) const
 {
     return getSamples(imageIndex.target, 0);
 }
 
+void Texture::setCrop(const gl::Rectangle& rect)
+{
+    mState.setCrop(rect);
+}
+
+const gl::Rectangle& Texture::getCrop() const
+{
+    return mState.getCrop();
+}
+
+void Texture::setGenerateMipmapHint(GLenum hint)
+{
+    mState.setGenerateMipmapHint(hint);
+}
+
+GLenum Texture::getGenerateMipmapHint() const
+{
+    return mState.getGenerateMipmapHint();
+}
+
 void Texture::onAttach(const Context *context)
 {
     addRef();
 }
 
 void Texture::onDetach(const Context *context)
 {
     release(context);
@@ -1427,26 +1477,28 @@ Error Texture::ensureInitialized(const C
 {
     if (!context->isRobustResourceInitEnabled() || mState.mInitState == InitState::Initialized)
     {
         return NoError();
     }
 
     bool anyDirty = false;
 
-    for (size_t descIndex = 0; descIndex < mState.mImageDescs.size(); ++descIndex)
+    ImageIndexIterator it =
+        ImageIndexIterator::MakeGeneric(mState.mType, 0, IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1);
+    while (it.hasNext())
     {
-        auto &imageDesc = mState.mImageDescs[descIndex];
-        if (imageDesc.initState == InitState::MayNeedInit)
+        const ImageIndex index = it.next();
+        ImageDesc &desc = mState.mImageDescs[GetImageDescIndex(index.target, index.mipIndex)];
+        if (desc.initState == InitState::MayNeedInit)
         {
             ASSERT(mState.mInitState == InitState::MayNeedInit);
-            const auto &imageIndex = GetImageIndexFromDescIndex(mState.mTarget, descIndex);
-            ANGLE_TRY(initializeContents(context, imageIndex));
-            imageDesc.initState = InitState::Initialized;
-            anyDirty            = true;
+            ANGLE_TRY(initializeContents(context, index));
+            desc.initState = InitState::Initialized;
+            anyDirty       = true;
         }
     }
     if (anyDirty)
     {
         signalDirty(context, InitState::Initialized);
     }
     mState.mInitState = InitState::Initialized;
 
@@ -1466,28 +1518,28 @@ InitState Texture::initState() const
 void Texture::setInitState(const ImageIndex &imageIndex, InitState initState)
 {
     ImageDesc newDesc = mState.getImageDesc(imageIndex);
     newDesc.initState = initState;
     mState.setImageDesc(imageIndex.target, imageIndex.mipIndex, newDesc);
 }
 
 Error Texture::ensureSubImageInitialized(const Context *context,
-                                         GLenum target,
+                                         TextureTarget target,
                                          size_t level,
                                          const gl::Box &area)
 {
     if (!context->isRobustResourceInitEnabled() || mState.mInitState == InitState::Initialized)
     {
         return NoError();
     }
 
     // Pre-initialize the texture contents if necessary.
     // TODO(jmadill): Check if area overlaps the entire texture.
-    const auto &imageIndex = GetImageIndexFromDescIndex(target, level);
+    ImageIndex imageIndex  = ImageIndex::MakeGeneric(target, static_cast<GLint>(level));
     const auto &desc       = mState.getImageDesc(imageIndex);
     if (desc.initState == InitState::MayNeedInit)
     {
         ASSERT(mState.mInitState == InitState::MayNeedInit);
         bool coversWholeImage = area.x == 0 && area.y == 0 && area.z == 0 &&
                                 area.width == desc.size.width && area.height == desc.size.height &&
                                 area.depth == desc.size.depth;
         if (!coversWholeImage)
--- a/gfx/angle/checkout/src/libANGLE/Texture.h
+++ b/gfx/angle/checkout/src/libANGLE/Texture.h
@@ -4,18 +4,18 @@
 // found in the LICENSE file.
 //
 
 // Texture.h: Defines the gl::Texture class [OpenGL ES 2.0.24] section 3.7 page 63.
 
 #ifndef LIBANGLE_TEXTURE_H_
 #define LIBANGLE_TEXTURE_H_
 
+#include <map>
 #include <vector>
-#include <map>
 
 #include "angle_gl.h"
 #include "common/Optional.h"
 #include "common/debug.h"
 #include "libANGLE/Caps.h"
 #include "libANGLE/Constants.h"
 #include "libANGLE/Debug.h"
 #include "libANGLE/Error.h"
@@ -85,71 +85,82 @@ struct SwizzleState final
     GLenum swizzleGreen;
     GLenum swizzleBlue;
     GLenum swizzleAlpha;
 };
 
 // State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec.
 struct TextureState final : private angle::NonCopyable
 {
-    TextureState(GLenum target);
+    TextureState(TextureType type);
     ~TextureState();
 
     bool swizzleRequired() const;
     GLuint getEffectiveBaseLevel() const;
     GLuint getEffectiveMaxLevel() const;
 
     // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10.
     GLuint getMipmapMaxLevel() const;
 
     // Returns true if base level changed.
     bool setBaseLevel(GLuint baseLevel);
     bool setMaxLevel(GLuint maxLevel);
 
     bool isCubeComplete() const;
 
-    const ImageDesc &getImageDesc(GLenum target, size_t level) const;
+    const ImageDesc &getImageDesc(TextureTarget target, size_t level) const;
     const ImageDesc &getImageDesc(const ImageIndex &imageIndex) const;
 
-    GLenum getTarget() const { return mTarget; }
+    TextureType getType() const { return mType; };
     const SwizzleState &getSwizzleState() const { return mSwizzleState; }
     const SamplerState &getSamplerState() const { return mSamplerState; }
     GLenum getUsage() const { return mUsage; }
     GLenum getDepthStencilTextureMode() const { return mDepthStencilTextureMode; }
 
+    // Returns the desc of the base level. Only valid for cube-complete/mip-complete textures.
+    const ImageDesc &getBaseLevelDesc() const;
+
+    // GLES1 emulation: For GL_OES_draw_texture
+    void setCrop(const gl::Rectangle& rect);
+    const gl::Rectangle& getCrop() const;
+
+    // GLES1 emulation: Auto-mipmap generation is a texparameter
+    void setGenerateMipmapHint(GLenum hint);
+    GLenum getGenerateMipmapHint() const;
+
   private:
     // Texture needs access to the ImageDesc functions.
     friend class Texture;
     // TODO(jmadill): Remove TextureGL from friends.
     friend class rx::TextureGL;
     friend bool operator==(const TextureState &a, const TextureState &b);
 
     bool computeSamplerCompleteness(const SamplerState &samplerState,
                                     const ContextState &data) const;
     bool computeMipmapCompleteness() const;
-    bool computeLevelCompleteness(GLenum target, size_t level) const;
+    bool computeLevelCompleteness(TextureTarget target, size_t level) const;
 
-    GLenum getBaseImageTarget() const;
+    TextureTarget getBaseImageTarget() const;
 
-    void setImageDesc(GLenum target, size_t level, const ImageDesc &desc);
+    void setImageDesc(TextureTarget target, size_t level, const ImageDesc &desc);
     void setImageDescChain(GLuint baselevel,
                            GLuint maxLevel,
                            Extents baseSize,
                            const Format &format,
                            InitState initState);
     void setImageDescChainMultisample(Extents baseSize,
                                       const Format &format,
                                       GLsizei samples,
                                       bool fixedSampleLocations,
                                       InitState initState);
 
-    void clearImageDesc(GLenum target, size_t level);
+    void clearImageDesc(TextureTarget target, size_t level);
     void clearImageDescs();
 
-    const GLenum mTarget;
+    const TextureType mType;
 
     SwizzleState mSwizzleState;
 
     SamplerState mSamplerState;
 
     GLuint mBaseLevel;
     GLuint mMaxLevel;
 
@@ -157,35 +168,42 @@ struct TextureState final : private angl
 
     bool mImmutableFormat;
     GLuint mImmutableLevels;
 
     // From GL_ANGLE_texture_usage
     GLenum mUsage;
 
     std::vector<ImageDesc> mImageDescs;
+
+    // GLES1 emulation: Texture crop rectangle
+    // For GL_OES_draw_texture
+    gl::Rectangle mCropRect;
+
+    // GLES1 emulation: Generate-mipmap hint per texture
+    GLenum mGenerateMipmapHint;
+
     InitState mInitState;
 };
 
 bool operator==(const TextureState &a, const TextureState &b);
 bool operator!=(const TextureState &a, const TextureState &b);
 
-class Texture final : public egl::ImageSibling,
-                      public LabeledObject
+class Texture final : public egl::ImageSibling, public LabeledObject
 {
   public:
-    Texture(rx::GLImplFactory *factory, GLuint id, GLenum target);
+    Texture(rx::GLImplFactory *factory, GLuint id, TextureType type);
     ~Texture() override;
 
     Error onDestroy(const Context *context) override;
 
     void setLabel(const std::string &label) override;
     const std::string &getLabel() const override;
 
-    GLenum getTarget() const;
+    TextureType getType() const;
 
     void setSwizzleRed(GLenum swizzleRed);
     GLenum getSwizzleRed() const;
 
     void setSwizzleGreen(GLenum swizzleGreen);
     GLenum getSwizzleGreen() const;
 
     void setSwizzleBlue(GLenum swizzleBlue);
@@ -242,112 +260,112 @@ class Texture final : public egl::ImageS
 
     GLuint getImmutableLevels() const;
 
     void setUsage(GLenum usage);
     GLenum getUsage() const;
 
     const TextureState &getTextureState() const;
 
-    size_t getWidth(GLenum target, size_t level) const;
-    size_t getHeight(GLenum target, size_t level) const;
-    size_t getDepth(GLenum target, size_t level) const;
-    GLsizei getSamples(GLenum target, size_t level) const;
-    bool getFixedSampleLocations(GLenum target, size_t level) const;
-    const Format &getFormat(GLenum target, size_t level) const;
+    size_t getWidth(TextureTarget target, size_t level) const;
+    size_t getHeight(TextureTarget target, size_t level) const;
+    size_t getDepth(TextureTarget target, size_t level) const;
+    GLsizei getSamples(TextureTarget target, size_t level) const;
+    bool getFixedSampleLocations(TextureTarget target, size_t level) const;
+    const Format &getFormat(TextureTarget target, size_t level) const;
 
     // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10.
     GLuint getMipmapMaxLevel() const;
 
     bool isMipmapComplete() const;
 
     Error setImage(const Context *context,
                    const PixelUnpackState &unpackState,
-                   GLenum target,
-                   size_t level,
+                   TextureTarget target,
+                   GLint level,
                    GLenum internalFormat,
                    const Extents &size,
                    GLenum format,
                    GLenum type,
                    const uint8_t *pixels);
     Error setSubImage(const Context *context,
                       const PixelUnpackState &unpackState,
-                      GLenum target,
-                      size_t level,
+                      TextureTarget target,
+                      GLint level,
                       const Box &area,
                       GLenum format,
                       GLenum type,
                       const uint8_t *pixels);
 
     Error setCompressedImage(const Context *context,
                              const PixelUnpackState &unpackState,
-                             GLenum target,
-                             size_t level,
+                             TextureTarget target,
+                             GLint level,
                              GLenum internalFormat,
                              const Extents &size,
                              size_t imageSize,
                              const uint8_t *pixels);
     Error setCompressedSubImage(const Context *context,
                                 const PixelUnpackState &unpackState,
-                                GLenum target,
-                                size_t level,
+                                TextureTarget target,
+                                GLint level,
                                 const Box &area,
                                 GLenum format,
                                 size_t imageSize,
                                 const uint8_t *pixels);
 
     Error copyImage(const Context *context,
-                    GLenum target,
-                    size_t level,
+                    TextureTarget target,
+                    GLint level,
                     const Rectangle &sourceArea,
                     GLenum internalFormat,
                     Framebuffer *source);
     Error copySubImage(const Context *context,
-                       GLenum target,
-                       size_t level,
+                       TextureTarget target,
+                       GLint level,
                        const Offset &destOffset,
                        const Rectangle &sourceArea,
                        Framebuffer *source);
 
     Error copyTexture(const Context *context,
-                      GLenum target,
-                      size_t level,
+                      TextureTarget target,
+                      GLint level,
                       GLenum internalFormat,
                       GLenum type,
-                      size_t sourceLevel,
+                      GLint sourceLevel,
                       bool unpackFlipY,
                       bool unpackPremultiplyAlpha,
                       bool unpackUnmultiplyAlpha,
                       Texture *source);
     Error copySubTexture(const Context *context,
-                         GLenum target,
-                         size_t level,
+                         TextureTarget target,
+                         GLint level,
                          const Offset &destOffset,
-                         size_t sourceLevel,
+                         GLint sourceLevel,
                          const Rectangle &sourceArea,
                          bool unpackFlipY,
                          bool unpackPremultiplyAlpha,
                          bool unpackUnmultiplyAlpha,
                          Texture *source);
     Error copyCompressedTexture(const Context *context, const Texture *source);
 
     Error setStorage(const Context *context,
-                     GLenum target,
+                     TextureType type,
                      GLsizei levels,
                      GLenum internalFormat,
                      const Extents &size);
 
     Error setStorageMultisample(const Context *context,
-                                GLenum target,
+                                TextureType type,
                                 GLsizei samples,
                                 GLint internalformat,
                                 const Extents &size,
                                 bool fixedSampleLocations);
 
-    Error setEGLImageTarget(const Context *context, GLenum target, egl::Image *imageTarget);
+    Error setEGLImageTarget(const Context *context, TextureType type, egl::Image *imageTarget);
 
     Error generateMipmap(const Context *context);
 
     egl::Surface *getBoundSurface() const;
     egl::Stream *getBoundStream() const;
 
     void signalDirty(const Context *context, InitState initState);
 
@@ -355,16 +373,22 @@ class Texture final : public egl::ImageS
 
     rx::TextureImpl *getImplementation() const { return mTexture; }
 
     // FramebufferAttachmentObject implementation
     Extents getAttachmentSize(const ImageIndex &imageIndex) const override;
     const Format &getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override;
     GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const override;
 
+    // GLES1 emulation
+    void setCrop(const gl::Rectangle& rect);
+    const gl::Rectangle& getCrop() const;
+    void setGenerateMipmapHint(GLenum generate);
+    GLenum getGenerateMipmapHint() const;
+
     void onAttach(const Context *context) override;
     void onDetach(const Context *context) override;
     GLuint getId() const override;
 
     // Needed for robust resource init.
     Error ensureInitialized(const Context *context);
     InitState initState(const ImageIndex &imageIndex) const override;
     InitState initState() const;
@@ -420,17 +444,17 @@ class Texture final : public egl::ImageS
     Error acquireImageFromStream(const Context *context,
                                  const egl::Stream::GLTextureDescription &desc);
     Error releaseImageFromStream(const Context *context);
 
     void invalidateCompletenessCache() const;
     Error releaseTexImageInternal(const Context *context);
 
     Error ensureSubImageInitialized(const Context *context,
-                                    GLenum target,
+                                    TextureTarget target,
                                     size_t level,
                                     const gl::Box &area);
 
     TextureState mState;
     DirtyBits mDirtyBits;
     rx::TextureImpl *mTexture;
 
     std::string mLabel;
--- a/gfx/angle/checkout/src/libANGLE/TransformFeedback.cpp
+++ b/gfx/angle/checkout/src/libANGLE/TransformFeedback.cpp
@@ -1,46 +1,72 @@
 //
 // Copyright (c) 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 "libANGLE/TransformFeedback.h"
 
+#include "common/mathutil.h"
 #include "libANGLE/Buffer.h"
 #include "libANGLE/Caps.h"
+#include "libANGLE/Context.h"
 #include "libANGLE/ContextState.h"
 #include "libANGLE/Program.h"
 #include "libANGLE/renderer/GLImplFactory.h"
 #include "libANGLE/renderer/TransformFeedbackImpl.h"
 
+#include <limits>
+
 namespace gl
 {
 
+angle::CheckedNumeric<GLsizeiptr> GetVerticesNeededForDraw(GLenum primitiveMode,
+                                                           GLsizei count,
+                                                           GLsizei primcount)
+{
+    if (count < 0 || primcount < 0)
+    {
+        return 0;
+    }
+    // Transform feedback only outputs complete primitives, so we need to round down to the nearest
+    // complete primitive before multiplying by the number of instances.
+    angle::CheckedNumeric<GLsizeiptr> checkedCount     = count;
+    angle::CheckedNumeric<GLsizeiptr> checkedPrimcount = primcount;
+    switch (primitiveMode)
+    {
+        case GL_TRIANGLES:
+            return checkedPrimcount * (checkedCount - checkedCount % 3);
+        case GL_LINES:
+            return checkedPrimcount * (checkedCount - checkedCount % 2);
+        case GL_POINTS:
+            return checkedPrimcount * checkedCount;
+        default:
+            NOTREACHED();
+            return checkedPrimcount * checkedCount;
+    }
+}
+
 TransformFeedbackState::TransformFeedbackState(size_t maxIndexedBuffers)
     : mLabel(),
       mActive(false),
       mPrimitiveMode(GL_NONE),
       mPaused(false),
+      mVerticesDrawn(0),
+      mVertexCapacity(0),
       mProgram(nullptr),
-      mGenericBuffer(),
       mIndexedBuffers(maxIndexedBuffers)
 {
 }
 
 TransformFeedbackState::~TransformFeedbackState()
 {
 }
 
-const BindingPointer<Buffer> &TransformFeedbackState::getGenericBuffer() const
-{
-    return mGenericBuffer;
-}
-
 const OffsetBindingPointer<Buffer> &TransformFeedbackState::getIndexedBuffer(size_t idx) const
 {
     return mIndexedBuffers[idx];
 }
 
 const std::vector<OffsetBindingPointer<Buffer>> &TransformFeedbackState::getIndexedBuffers() const
 {
     return mIndexedBuffers;
@@ -51,24 +77,24 @@ TransformFeedback::TransformFeedback(rx:
       mState(caps.maxTransformFeedbackSeparateAttributes),
       mImplementation(implFactory->createTransformFeedback(mState))
 {
     ASSERT(mImplementation != nullptr);
 }
 
 Error TransformFeedback::onDestroy(const Context *context)
 {
+    ASSERT(!context || !context->isCurrentTransformFeedback(this));
     if (mState.mProgram)
     {
         mState.mProgram->release(context);
         mState.mProgram = nullptr;
     }
 
     ASSERT(!mState.mProgram);
-    mState.mGenericBuffer.set(context, nullptr);
     for (size_t i = 0; i < mState.mIndexedBuffers.size(); i++)
     {
         mState.mIndexedBuffers[i].set(context, nullptr);
     }
 
     return NoError();
 }
 
@@ -87,25 +113,47 @@ const std::string &TransformFeedback::ge
     return mState.mLabel;
 }
 
 void TransformFeedback::begin(const Context *context, GLenum primitiveMode, Program *program)
 {
     mState.mActive        = true;
     mState.mPrimitiveMode = primitiveMode;
     mState.mPaused        = false;
+    mState.mVerticesDrawn = 0;
     mImplementation->begin(primitiveMode);
     bindProgram(context, program);
+
+    if (program)
+    {
+        // Compute the number of vertices we can draw before overflowing the bound buffers.
+        auto strides = program->getTransformFeedbackStrides();
+        ASSERT(strides.size() <= mState.mIndexedBuffers.size() && !strides.empty());
+        GLsizeiptr minCapacity = std::numeric_limits<GLsizeiptr>::max();
+        for (size_t index = 0; index < strides.size(); index++)
+        {
+            GLsizeiptr capacity =
+                GetBoundBufferAvailableSize(mState.mIndexedBuffers[index]) / strides[index];
+            minCapacity = std::min(minCapacity, capacity);
+        }
+        mState.mVertexCapacity = minCapacity;
+    }
+    else
+    {
+        mState.mVertexCapacity = 0;
+    }
 }
 
 void TransformFeedback::end(const Context *context)
 {
-    mState.mActive        = false;
-    mState.mPrimitiveMode = GL_NONE;
-    mState.mPaused        = false;
+    mState.mActive         = false;
+    mState.mPrimitiveMode  = GL_NONE;
+    mState.mPaused         = false;
+    mState.mVerticesDrawn  = 0;
+    mState.mVertexCapacity = 0;
     mImplementation->end();
     if (mState.mProgram)
     {
         mState.mProgram->release(context);
         mState.mProgram = nullptr;
     }
 }
 
@@ -131,16 +179,40 @@ bool TransformFeedback::isPaused() const
     return mState.mPaused;
 }
 
 GLenum TransformFeedback::getPrimitiveMode() const
 {
     return mState.mPrimitiveMode;
 }
 
+bool TransformFeedback::checkBufferSpaceForDraw(GLsizei count, GLsizei primcount) const
+{
+    auto vertices =
+        mState.mVerticesDrawn + GetVerticesNeededForDraw(mState.mPrimitiveMode, count, primcount);
+    return vertices.IsValid() && vertices.ValueOrDie() <= mState.mVertexCapacity;
+}
+
+void TransformFeedback::onVerticesDrawn(const Context *context, GLsizei count, GLsizei primcount)
+{
+    ASSERT(mState.mActive && !mState.mPaused);
+    // All draws should be validated with checkBufferSpaceForDraw so ValueOrDie should never fail.
+    mState.mVerticesDrawn =
+        (mState.mVerticesDrawn + GetVerticesNeededForDraw(mState.mPrimitiveMode, count, primcount))
+            .ValueOrDie();
+
+    for (auto &buffer : mState.mIndexedBuffers)
+    {
+        if (buffer.get() != nullptr)
+        {
+            buffer->onTransformFeedback(context);
+        }
+    }
+}
+
 void TransformFeedback::bindProgram(const Context *context, Program *program)
 {
     if (mState.mProgram != program)
     {
         if (mState.mProgram != nullptr)
         {
             mState.mProgram->release(context);
         }
@@ -152,70 +224,91 @@ void TransformFeedback::bindProgram(cons
     }
 }
 
 bool TransformFeedback::hasBoundProgram(GLuint program) const
 {
     return mState.mProgram != nullptr && mState.mProgram->id() == program;
 }
 
-void TransformFeedback::bindGenericBuffer(const Context *context, Buffer *buffer)
-{
-    mState.mGenericBuffer.set(context, buffer);
-    mImplementation->bindGenericBuffer(mState.mGenericBuffer);
-}
-
 void TransformFeedback::detachBuffer(const Context *context, GLuint bufferName)
 {
+    bool isBound = context->isCurrentTransformFeedback(this);
     for (size_t index = 0; index < mState.mIndexedBuffers.size(); index++)
     {
         if (mState.mIndexedBuffers[index].id() == bufferName)
         {
+            if (isBound)
+            {
+                mState.mIndexedBuffers[index]->onBindingChanged(false,
+                                                                BufferBinding::TransformFeedback);
+            }
             mState.mIndexedBuffers[index].set(context, nullptr);
             mImplementation->bindIndexedBuffer(index, mState.mIndexedBuffers[index]);
         }
     }
-
-    if (mState.mGenericBuffer.id() == bufferName)
-    {
-        mState.mGenericBuffer.set(context, nullptr);
-        mImplementation->bindGenericBuffer(mState.mGenericBuffer);
-    }
-}
-
-const BindingPointer<Buffer> &TransformFeedback::getGenericBuffer() const
-{
-    return mState.mGenericBuffer;
 }
 
 void TransformFeedback::bindIndexedBuffer(const Context *context,
                                           size_t index,
                                           Buffer *buffer,
                                           size_t offset,
                                           size_t size)
 {
     ASSERT(index < mState.mIndexedBuffers.size());
+    bool isBound = context && context->isCurrentTransformFeedback(this);
+    if (isBound && mState.mIndexedBuffers[index].get())
+    {
+        mState.mIndexedBuffers[index]->onBindingChanged(false, BufferBinding::TransformFeedback);
+    }
     mState.mIndexedBuffers[index].set(context, buffer, offset, size);
+    if (isBound && buffer)
+    {
+        buffer->onBindingChanged(true, BufferBinding::TransformFeedback);
+    }
+
     mImplementation->bindIndexedBuffer(index, mState.mIndexedBuffers[index]);
 }
 
 const OffsetBindingPointer<Buffer> &TransformFeedback::getIndexedBuffer(size_t index) const
 {
     ASSERT(index < mState.mIndexedBuffers.size());
     return mState.mIndexedBuffers[index];
 }
 
 size_t TransformFeedback::getIndexedBufferCount() const
 {
     return mState.mIndexedBuffers.size();
 }
 
+bool TransformFeedback::buffersBoundForOtherUse() const
+{
+    for (auto &buffer : mState.mIndexedBuffers)
+    {
+        if (buffer.get() && buffer->isBoundForTransformFeedbackAndOtherUse())
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
 rx::TransformFeedbackImpl *TransformFeedback::getImplementation()
 {
     return mImplementation;
 }
 
 const rx::TransformFeedbackImpl *TransformFeedback::getImplementation() const
 {
     return mImplementation;
 }
 
+void TransformFeedback::onBindingChanged(bool bound)
+{
+    for (auto &buffer : mState.mIndexedBuffers)
+    {
+        if (buffer.get())
+        {
+            buffer->onBindingChanged(bound, BufferBinding::TransformFeedback);
+        }
+    }
 }
+}
--- a/gfx/angle/checkout/src/libANGLE/TransformFeedback.h
+++ b/gfx/angle/checkout/src/libANGLE/TransformFeedback.h
@@ -28,32 +28,32 @@ class Context;
 class Program;
 
 class TransformFeedbackState final : angle::NonCopyable
 {
   public:
     TransformFeedbackState(size_t maxIndexedBuffers);
     ~TransformFeedbackState();
 
-    const BindingPointer<Buffer> &getGenericBuffer() const;
     const OffsetBindingPointer<Buffer> &getIndexedBuffer(size_t idx) const;
     const std::vector<OffsetBindingPointer<Buffer>> &getIndexedBuffers() const;
 
   private:
     friend class TransformFeedback;
 
     std::string mLabel;
 
     bool mActive;
     GLenum mPrimitiveMode;
     bool mPaused;
+    GLsizeiptr mVerticesDrawn;
+    GLsizeiptr mVertexCapacity;
 
     Program *mProgram;
 
-    BindingPointer<Buffer> mGenericBuffer;
     std::vector<OffsetBindingPointer<Buffer>> mIndexedBuffers;
 };
 
 class TransformFeedback final : public RefCountObject, public LabeledObject
 {
   public:
     TransformFeedback(rx::GLImplFactory *implFactory, GLuint id, const Caps &caps);
     ~TransformFeedback() override;
@@ -65,35 +65,45 @@ class TransformFeedback final : public R
     void begin(const Context *context, GLenum primitiveMode, Program *program);
     void end(const Context *context);
     void pause();
     void resume();
 
     bool isActive() const;
     bool isPaused() const;
     GLenum getPrimitiveMode() const;
+    // Validates that the vertices produced by a draw call will fit in the bound transform feedback
+    // buffers.
+    bool checkBufferSpaceForDraw(GLsizei count, GLsizei primcount) const;
+    // This must be called after each draw call when transform feedback is enabled to keep track of
+    // how many vertices have been written to the buffers. This information is needed by
+    // checkBufferSpaceForDraw because each draw call appends vertices to the buffers starting just
+    // after the last vertex of the previous draw call.
+    void onVerticesDrawn(const Context *context, GLsizei count, GLsizei primcount);
 
     bool hasBoundProgram(GLuint program) const;
 
-    void bindGenericBuffer(const Context *context, Buffer *buffer);
-    const BindingPointer<Buffer> &getGenericBuffer() const;
-
     void bindIndexedBuffer(const Context *context,
                            size_t index,
                            Buffer *buffer,
                            size_t offset,
                            size_t size);
     const OffsetBindingPointer<Buffer> &getIndexedBuffer(size_t index) const;
     size_t getIndexedBufferCount() const;
 
+    // Returns true if any buffer bound to this object is also bound to another target.
+    bool buffersBoundForOtherUse() const;
+
     void detachBuffer(const Context *context, GLuint bufferName);
 
     rx::TransformFeedbackImpl *getImplementation();
     const rx::TransformFeedbackImpl *getImplementation() const;
 
+    void onBindingChanged(bool bound);
+
   private:
     void bindProgram(const Context *context, Program *program);
 
     TransformFeedbackState mState;
     rx::TransformFeedbackImpl* mImplementation;
 };
 
 }
--- a/gfx/angle/checkout/src/libANGLE/Uniform.cpp
+++ b/gfx/angle/checkout/src/libANGLE/Uniform.cpp
@@ -8,54 +8,47 @@
 
 #include "common/utilities.h"
 
 #include <cstring>
 
 namespace gl
 {
 
-StaticallyUsed::StaticallyUsed()
-    : vertexStaticUse(false), fragmentStaticUse(false), computeStaticUse(false)
+ActiveVariable::ActiveVariable()
 {
 }
 
-StaticallyUsed::~StaticallyUsed()
+ActiveVariable::~ActiveVariable()
 {
 }
 
-StaticallyUsed::StaticallyUsed(const StaticallyUsed &rhs) = default;
-StaticallyUsed &StaticallyUsed::operator=(const StaticallyUsed &rhs) = default;
-
-void StaticallyUsed::setStaticUse(GLenum shaderType, bool used)
-{
-    switch (shaderType)
-    {
-        case GL_VERTEX_SHADER:
-            vertexStaticUse = used;
-            break;
+ActiveVariable::ActiveVariable(const ActiveVariable &rhs) = default;
+ActiveVariable &ActiveVariable::operator=(const ActiveVariable &rhs) = default;
 
-        case GL_FRAGMENT_SHADER:
-            fragmentStaticUse = used;
-            break;
-
-        case GL_COMPUTE_SHADER:
-            computeStaticUse = used;
-            break;
-
-        default:
-            UNREACHABLE();
-    }
+void ActiveVariable::setActive(ShaderType shaderType, bool used)
+{
+    ASSERT(shaderType != ShaderType::InvalidEnum);
+    mActiveUseBits.set(shaderType, used);
 }
 
-void StaticallyUsed::unionReferencesWith(const StaticallyUsed &other)
+bool ActiveVariable::isActive(ShaderType shaderType) const
 {
-    vertexStaticUse |= other.vertexStaticUse;
-    fragmentStaticUse |= other.fragmentStaticUse;
-    computeStaticUse |= other.computeStaticUse;
+    ASSERT(shaderType != ShaderType::InvalidEnum);
+    return mActiveUseBits[shaderType];
+}
+
+void ActiveVariable::unionReferencesWith(const ActiveVariable &other)
+{
+    mActiveUseBits |= other.mActiveUseBits;
+}
+
+ShaderType ActiveVariable::getFirstShaderTypeWhereActive() const
+{
+    return static_cast<ShaderType>(gl::ScanForward(mActiveUseBits.bits()));
 }
 
 LinkedUniform::LinkedUniform()
     : typeInfo(nullptr), bufferIndex(-1), blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo())
 {
 }
 
 LinkedUniform::LinkedUniform(GLenum typeIn,
@@ -87,27 +80,27 @@ LinkedUniform::LinkedUniform(const sh::U
       blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo())
 {
     ASSERT(!isArrayOfArrays());
     ASSERT(!isArray() || !isStruct());
 }
 
 LinkedUniform::LinkedUniform(const LinkedUniform &uniform)
     : sh::Uniform(uniform),
-      StaticallyUsed(uniform),
+      ActiveVariable(uniform),
       typeInfo(uniform.typeInfo),
       bufferIndex(uniform.bufferIndex),
       blockInfo(uniform.blockInfo)
 {
 }
 
 LinkedUniform &LinkedUniform::operator=(const LinkedUniform &uniform)
 {
     sh::Uniform::operator=(uniform);
-    StaticallyUsed::operator=(uniform);
+    ActiveVariable::operator=(uniform);
     typeInfo             = uniform.typeInfo;
     bufferIndex          = uniform.bufferIndex;
     blockInfo            = uniform.blockInfo;
     return *this;
 }
 
 LinkedUniform::~LinkedUniform()
 {
--- a/gfx/angle/checkout/src/libANGLE/Uniform.h
+++ b/gfx/angle/checkout/src/libANGLE/Uniform.h
@@ -15,34 +15,35 @@
 #include "common/MemoryBuffer.h"
 #include "compiler/translator/blocklayout.h"
 #include "libANGLE/angletypes.h"
 
 namespace gl
 {
 struct UniformTypeInfo;
 
-struct StaticallyUsed
+struct ActiveVariable
 {
-    StaticallyUsed();
-    StaticallyUsed(const StaticallyUsed &rhs);
-    virtual ~StaticallyUsed();
+    ActiveVariable();
+    ActiveVariable(const ActiveVariable &rhs);
+    virtual ~ActiveVariable();
+
+    ActiveVariable &operator=(const ActiveVariable &rhs);
 
-    StaticallyUsed &operator=(const StaticallyUsed &rhs);
+    ShaderType getFirstShaderTypeWhereActive() const;
+    void setActive(ShaderType shaderType, bool used);
+    void unionReferencesWith(const ActiveVariable &other);
+    bool isActive(ShaderType shaderType) const;
 
-    void setStaticUse(GLenum shaderType, bool used);
-    void unionReferencesWith(const StaticallyUsed &other);
-
-    bool vertexStaticUse;
-    bool fragmentStaticUse;
-    bool computeStaticUse;
+  private:
+    ShaderBitSet mActiveUseBits;
 };
 
 // Helper struct representing a single shader uniform
-struct LinkedUniform : public sh::Uniform, public StaticallyUsed
+struct LinkedUniform : public sh::Uniform, public ActiveVariable
 {
     LinkedUniform();
     LinkedUniform(GLenum type,
                   GLenum precision,
                   const std::string &name,
                   const std::vector<unsigned int> &arraySizes,
                   const int binding,
                   const int offset,
@@ -64,17 +65,17 @@ struct LinkedUniform : public sh::Unifor
 
     const UniformTypeInfo *typeInfo;
 
     // Identifies the containing buffer backed resource -- interface block or atomic counter buffer.
     int bufferIndex;
     sh::BlockMemberInfo blockInfo;
 };
 
-struct BufferVariable : public sh::ShaderVariable, public StaticallyUsed
+struct BufferVariable : public sh::ShaderVariable, public ActiveVariable
 {
     BufferVariable();
     BufferVariable(GLenum type,
                    GLenum precision,
                    const std::string &name,
                    const std::vector<unsigned int> &arraySizes,
                    const int bufferIndex,
                    const sh::BlockMemberInfo &blockInfo);
@@ -83,17 +84,17 @@ struct BufferVariable : public sh::Shade
     int bufferIndex;
     sh::BlockMemberInfo blockInfo;
 
     int topLevelArraySize;
 };
 
 // Parent struct for atomic counter, uniform block, and shader storage block buffer, which all
 // contain a group of shader variables, and have a GL buffer backed.
-struct ShaderVariableBuffer : public StaticallyUsed
+struct ShaderVariableBuffer : public ActiveVariable
 {
     ShaderVariableBuffer();
     ShaderVariableBuffer(const ShaderVariableBuffer &other);
     ~ShaderVariableBuffer() override;
     int numActiveVariables() const;
 
     int binding;
     unsigned int dataSize;
--- a/gfx/angle/checkout/src/libANGLE/VaryingPacking.cpp
+++ b/gfx/angle/checkout/src/libANGLE/VaryingPacking.cpp
@@ -287,20 +287,23 @@ bool VaryingPacking::collectAndPackUserV
     mPackedVaryings.clear();
 
     for (const auto &ref : mergedVaryings)
     {
         const sh::Varying *input  = ref.second.vertex;
         const sh::Varying *output = ref.second.fragment;
 
         // Only pack statically used varyings that have a matched input or output, plus special
-        // builtins.
+        // builtins. Note that we pack all statically used user-defined varyings even if they are
+        // not active. GLES specs are a bit vague on whether it's allowed to only pack active
+        // varyings, though GLES 3.1 spec section 11.1.2.1 says that "device-dependent
+        // optimizations" may be used to make vertex shader outputs fit.
         if ((input && output && output->staticUse) ||
-            (input && input->isBuiltIn() && input->staticUse) ||
-            (output && output->isBuiltIn() && output->staticUse))
+            (input && input->isBuiltIn() && input->active) ||
+            (output && output->isBuiltIn() && output->active))
         {
             const sh::Varying *varying = output ? output : input;
 
             // Don't count gl_Position. Also don't count gl_PointSize for D3D9.
             if (varying->name != "gl_Position" &&
                 !(varying->name == "gl_PointSize" &&
                   mPackMode == PackMode::ANGLE_NON_CONFORMANT_D3D9))
             {
--- a/gfx/angle/checkout/src/libANGLE/VertexArray.cpp
+++ b/gfx/angle/checkout/src/libANGLE/VertexArray.cpp
@@ -4,16 +4,17 @@
 // found in the LICENSE file.
 //
 // Implementation of the state class for mananging GLES 3 Vertex Array Objects.
 //
 
 #include "libANGLE/VertexArray.h"
 #include "libANGLE/Buffer.h"
 #include "libANGLE/Context.h"
+#include "libANGLE/renderer/BufferImpl.h"
 #include "libANGLE/renderer/GLImplFactory.h"
 #include "libANGLE/renderer/VertexArrayImpl.h"
 
 namespace gl
 {
 
 VertexArrayState::VertexArrayState(size_t maxAttribs, size_t maxAttribBindings)
     : mLabel(), mVertexBindings(maxAttribBindings)
@@ -31,26 +32,34 @@ VertexArrayState::~VertexArrayState()
 }
 
 VertexArray::VertexArray(rx::GLImplFactory *factory,
                          GLuint id,
                          size_t maxAttribs,
                          size_t maxAttribBindings)
     : mId(id),
       mState(maxAttribs, maxAttribBindings),
-      mVertexArray(factory->createVertexArray(mState))
+      mVertexArray(factory->createVertexArray(mState)),
+      mElementArrayBufferObserverBinding(this, maxAttribBindings)
 {
+    for (size_t attribIndex = 0; attribIndex < maxAttribBindings; ++attribIndex)
+    {
+        mArrayBufferObserverBindings.emplace_back(this, attribIndex);
+    }
 }
 
 void VertexArray::onDestroy(const Context *context)
 {
+    bool isBound = context->isCurrentVertexArray(this);
     for (auto &binding : mState.mVertexBindings)
     {
-        binding.setBuffer(context, nullptr);
+        binding.setBuffer(context, nullptr, isBound);
     }
+    if (isBound && mState.mElementArrayBuffer.get())
+        mState.mElementArrayBuffer->onBindingChanged(false, BufferBinding::ElementArray);
     mState.mElementArrayBuffer.set(context, nullptr);
     mVertexArray->destroy(context);
     SafeDelete(mVertexArray);
     delete this;
 }
 
 VertexArray::~VertexArray()
 {
@@ -69,26 +78,29 @@ void VertexArray::setLabel(const std::st
 
 const std::string &VertexArray::getLabel() const
 {
     return mState.mLabel;
 }
 
 void VertexArray::detachBuffer(const Context *context, GLuint bufferName)
 {
+    bool isBound = context->isCurrentVertexArray(this);
     for (auto &binding : mState.mVertexBindings)
     {
         if (binding.getBuffer().id() == bufferName)
         {
-            binding.setBuffer(context, nullptr);
+            binding.setBuffer(context, nullptr, isBound);
         }
     }
 
     if (mState.mElementArrayBuffer.id() == bufferName)
     {
+        if (isBound && mState.mElementArrayBuffer.get())
+            mState.mElementArrayBuffer->onBindingChanged(false, BufferBinding::Array);
         mState.mElementArrayBuffer.set(context, nullptr);
     }
 }
 
 const VertexAttribute &VertexArray::getVertexAttribute(size_t attribIndex) const
 {
     ASSERT(attribIndex < getMaxAttribs());
     return mState.mVertexAttributes[attribIndex];
@@ -100,68 +112,82 @@ const VertexBinding &VertexArray::getVer
     return mState.mVertexBindings[bindingIndex];
 }
 
 size_t VertexArray::GetVertexIndexFromDirtyBit(size_t dirtyBit)
 {
     static_assert(gl::MAX_VERTEX_ATTRIBS == gl::MAX_VERTEX_ATTRIB_BINDINGS,
                   "The stride of vertex attributes should equal to that of vertex bindings.");
     ASSERT(dirtyBit > DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
-    return (dirtyBit - DIRTY_BIT_ATTRIB_0_ENABLED) % gl::MAX_VERTEX_ATTRIBS;
+    return (dirtyBit - DIRTY_BIT_ATTRIB_0) % gl::MAX_VERTEX_ATTRIBS;
+}
+
+void VertexArray::setDirtyAttribBit(size_t attribIndex, DirtyAttribBitType dirtyAttribBit)
+{
+    mDirtyBits.set(DIRTY_BIT_ATTRIB_0 + attribIndex);
+    mDirtyAttribBits[attribIndex].set(dirtyAttribBit);
+}
+
+void VertexArray::setDirtyBindingBit(size_t bindingIndex, DirtyBindingBitType dirtyBindingBit)
+{
+    mDirtyBits.set(DIRTY_BIT_BINDING_0 + bindingIndex);
+    mDirtyBindingBits[bindingIndex].set(dirtyBindingBit);
 }
 
 void VertexArray::bindVertexBufferImpl(const Context *context,
                                        size_t bindingIndex,
                                        Buffer *boundBuffer,
                                        GLintptr offset,
                                        GLsizei stride)
 {
     ASSERT(bindingIndex < getMaxBindings());
+    bool isBound = context->isCurrentVertexArray(this);
 
     VertexBinding *binding = &mState.mVertexBindings[bindingIndex];
 
-    binding->setBuffer(context, boundBuffer);
+    binding->setBuffer(context, boundBuffer, isBound);
     binding->setOffset(offset);
     binding->setStride(stride);
+
+    updateObserverBinding(bindingIndex);
 }
 
 void VertexArray::bindVertexBuffer(const Context *context,
                                    size_t bindingIndex,
                                    Buffer *boundBuffer,
                                    GLintptr offset,
                                    GLsizei stride)
 {
     bindVertexBufferImpl(context, bindingIndex, boundBuffer, offset, stride);
-
-    mDirtyBits.set(DIRTY_BIT_BINDING_0_BUFFER + bindingIndex);
+    setDirtyBindingBit(bindingIndex, DIRTY_BINDING_BUFFER);
 }
 
 void VertexArray::setVertexAttribBinding(const Context *context,
                                          size_t attribIndex,
                                          GLuint bindingIndex)
 {
     ASSERT(attribIndex < getMaxAttribs() && bindingIndex < getMaxBindings());
 
     if (mState.mVertexAttributes[attribIndex].bindingIndex != bindingIndex)
     {
         // In ES 3.0 contexts, the binding cannot change, hence the code below is unreachable.
         ASSERT(context->getClientVersion() >= ES_3_1);
         mState.mVertexAttributes[attribIndex].bindingIndex = bindingIndex;
 
-        mDirtyBits.set(DIRTY_BIT_ATTRIB_0_BINDING + attribIndex);
+        setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_BINDING);
     }
+    mState.mVertexAttributes[attribIndex].bindingIndex = static_cast<GLuint>(bindingIndex);
 }
 
 void VertexArray::setVertexBindingDivisor(size_t bindingIndex, GLuint divisor)
 {
     ASSERT(bindingIndex < getMaxBindings());
 
     mState.mVertexBindings[bindingIndex].setDivisor(divisor);
-
-    mDirtyBits.set(DIRTY_BIT_BINDING_0_DIVISOR + bindingIndex);
+    setDirtyBindingBit(bindingIndex, DIRTY_BINDING_DIVISOR);
 }
 
 void VertexArray::setVertexAttribFormatImpl(size_t attribIndex,
                                             GLint size,
                                             GLenum type,
                                             bool normalized,
                                             bool pureInteger,
                                             GLuint relativeOffset)
@@ -182,18 +208,17 @@ void VertexArray::setVertexAttribFormatI
 void VertexArray::setVertexAttribFormat(size_t attribIndex,
                                         GLint size,
                                         GLenum type,
                                         bool normalized,
                                         bool pureInteger,
                                         GLuint relativeOffset)
 {
     setVertexAttribFormatImpl(attribIndex, size, type, normalized, pureInteger, relativeOffset);
-
-    mDirtyBits.set(DIRTY_BIT_ATTRIB_0_FORMAT + attribIndex);
+    setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_FORMAT);
 }
 
 void VertexArray::setVertexAttribDivisor(const Context *context, size_t attribIndex, GLuint divisor)
 {
     ASSERT(attribIndex < getMaxAttribs());
 
     setVertexAttribBinding(context, attribIndex, static_cast<GLuint>(attribIndex));
     setVertexBindingDivisor(attribIndex, divisor);
@@ -202,17 +227,17 @@ void VertexArray::setVertexAttribDivisor
 void VertexArray::enableAttribute(size_t attribIndex, bool enabledState)
 {
     ASSERT(attribIndex < getMaxAttribs());
 
     mState.mVertexAttributes[attribIndex].enabled = enabledState;
     mState.mVertexAttributesTypeMask.setIndex(
         GetVertexAttributeBaseType(mState.mVertexAttributes[attribIndex]), attribIndex);
 
-    mDirtyBits.set(DIRTY_BIT_ATTRIB_0_ENABLED + attribIndex);
+    setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_ENABLED);
 
     // Update state cache
     mState.mEnabledAttributesMask.set(attribIndex, enabledState);
 }
 
 void VertexArray::setVertexAttribPointer(const Context *context,
                                          size_t attribIndex,
                                          gl::Buffer *boundBuffer,
@@ -234,27 +259,89 @@ void VertexArray::setVertexAttribPointer
 
     GLsizei effectiveStride =
         stride != 0 ? stride : static_cast<GLsizei>(ComputeVertexAttributeTypeSize(attrib));
     attrib.pointer                 = pointer;
     attrib.vertexAttribArrayStride = stride;
 
     bindVertexBufferImpl(context, attribIndex, boundBuffer, offset, effectiveStride);
 
-    mDirtyBits.set(DIRTY_BIT_ATTRIB_0_POINTER + attribIndex);
+    setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_POINTER);
 }
 
 void VertexArray::setElementArrayBuffer(const Context *context, Buffer *buffer)
 {
+    bool isBound = context->isCurrentVertexArray(this);
+    if (isBound && mState.mElementArrayBuffer.get())
+        mState.mElementArrayBuffer->onBindingChanged(false, BufferBinding::ElementArray);
     mState.mElementArrayBuffer.set(context, buffer);
+    if (isBound && mState.mElementArrayBuffer.get())
+        mState.mElementArrayBuffer->onBindingChanged(true, BufferBinding::ElementArray);
+    mElementArrayBufferObserverBinding.bind(buffer ? buffer->getImplementation() : nullptr);
     mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
 }
 
-void VertexArray::syncState(const Context *context)
+gl::Error VertexArray::syncState(const Context *context)
 {
     if (mDirtyBits.any())
     {
-        mVertexArray->syncState(context, mDirtyBits);
+        mDirtyBitsGuard = mDirtyBits;
+        ANGLE_TRY(
+            mVertexArray->syncState(context, mDirtyBits, mDirtyAttribBits, mDirtyBindingBits));
         mDirtyBits.reset();
+        mDirtyBitsGuard.reset();
+
+        // This is a bit of an implementation hack - but since we know the implementation
+        // details of the dirty bit class it should always have the same effect as iterating
+        // individual attribs. We could also look into schemes where iterating the dirty
+        // bit set also resets it as you pass through it.
+        memset(&mDirtyAttribBits, 0, sizeof(mDirtyAttribBits));
+        memset(&mDirtyBindingBits, 0, sizeof(mDirtyBindingBits));
+    }
+    return gl::NoError();
+}
+
+void VertexArray::onBindingChanged(bool bound)
+{
+    if (mState.mElementArrayBuffer.get())
+        mState.mElementArrayBuffer->onBindingChanged(bound, BufferBinding::ElementArray);
+    for (auto &binding : mState.mVertexBindings)
+    {
+        binding.onContainerBindingChanged(bound);
     }
 }
 
+VertexArray::DirtyBitType VertexArray::getDirtyBitFromIndex(bool contentsChanged,
+                                                            angle::SubjectIndex index) const
+{
+    if (index == mArrayBufferObserverBindings.size())
+    {
+        return contentsChanged ? DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA
+                               : DIRTY_BIT_ELEMENT_ARRAY_BUFFER;
+    }
+    else
+    {
+        // Note: this currently just gets the top-level dirty bit.
+        ASSERT(index < mArrayBufferObserverBindings.size());
+        return static_cast<DirtyBitType>(
+            (contentsChanged ? DIRTY_BIT_BUFFER_DATA_0 : DIRTY_BIT_BINDING_0) + index);
+    }
+}
+
+void VertexArray::onSubjectStateChange(const gl::Context *context,
+                                       angle::SubjectIndex index,
+                                       angle::SubjectMessage message)
+{
+    bool contentsChanged  = (message == angle::SubjectMessage::CONTENTS_CHANGED);
+    DirtyBitType dirtyBit = getDirtyBitFromIndex(contentsChanged, index);
+    ASSERT(!mDirtyBitsGuard.valid() || mDirtyBitsGuard.value().test(dirtyBit));
+    mDirtyBits.set(dirtyBit);
+    context->getGLState().setVertexArrayDirty(this);
+}
+
+void VertexArray::updateObserverBinding(size_t bindingIndex)
+{
+    Buffer *boundBuffer = mState.mVertexBindings[bindingIndex].getBuffer().get();
+    mArrayBufferObserverBindings[bindingIndex].bind(boundBuffer ? boundBuffer->getImplementation()
+                                                                : nullptr);
+}
+
 }  // namespace gl
--- a/gfx/angle/checkout/src/libANGLE/VertexArray.h
+++ b/gfx/angle/checkout/src/libANGLE/VertexArray.h
@@ -8,19 +8,20 @@
 //   The buffer objects that are to be used by the vertex stage of the GL are collected
 //   together to form a vertex array object. All state related to the definition of data used
 //   by the vertex processor is encapsulated in a vertex array object.
 //
 
 #ifndef LIBANGLE_VERTEXARRAY_H_
 #define LIBANGLE_VERTEXARRAY_H_
 
-#include "libANGLE/RefCountObject.h"
 #include "libANGLE/Constants.h"
 #include "libANGLE/Debug.h"
+#include "libANGLE/Observer.h"
+#include "libANGLE/RefCountObject.h"
 #include "libANGLE/State.h"
 #include "libANGLE/VertexAttribute.h"
 
 #include <vector>
 
 namespace rx
 {
 class GLImplFactory;
@@ -67,17 +68,17 @@ class VertexArrayState final : angle::No
     std::string mLabel;
     std::vector<VertexAttribute> mVertexAttributes;
     BindingPointer<Buffer> mElementArrayBuffer;
     std::vector<VertexBinding> mVertexBindings;
     AttributesMask mEnabledAttributesMask;
     ComponentTypeMask mVertexAttributesTypeMask;
 };
 
-class VertexArray final : public LabeledObject
+class VertexArray final : public angle::ObserverInterface, public LabeledObject
 {
   public:
     VertexArray(rx::GLImplFactory *factory, GLuint id, size_t maxAttribs, size_t maxAttribBindings);
 
     void onDestroy(const Context *context);
 
     GLuint id() const;
 
@@ -148,65 +149,103 @@ class VertexArray final : public Labeled
 
     rx::VertexArrayImpl *getImplementation() const { return mVertexArray; }
 
     const AttributesMask &getEnabledAttributesMask() const
     {
         return mState.getEnabledAttributesMask();
     }
 
+    // Observer implementation
+    void onSubjectStateChange(const gl::Context *context,
+                              angle::SubjectIndex index,
+                              angle::SubjectMessage message) override;
+
+    // Dirty bits for VertexArrays use a heirarchical design. At the top level, each attribute
+    // has a single dirty bit. Then an array of MAX_ATTRIBS dirty bits each has a dirty bit for
+    // enabled/pointer/format/binding. Bindings are handled similarly. Note that because the
+    // total number of dirty bits is 33, it will not be as fast on a 32-bit machine, which
+    // can't support the advanced 64-bit scanning intrinsics. We could consider packing the
+    // binding and attribute bits together if this becomes a problem.
     enum DirtyBitType
     {
         DIRTY_BIT_ELEMENT_ARRAY_BUFFER,
-
-        // Reserve bits for enabled flags
-        DIRTY_BIT_ATTRIB_0_ENABLED,
-        DIRTY_BIT_ATTRIB_MAX_ENABLED = DIRTY_BIT_ATTRIB_0_ENABLED + gl::MAX_VERTEX_ATTRIBS,
+        DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA,
 
-        // Reserve bits for attrib pointers
-        DIRTY_BIT_ATTRIB_0_POINTER   = DIRTY_BIT_ATTRIB_MAX_ENABLED,
-        DIRTY_BIT_ATTRIB_MAX_POINTER = DIRTY_BIT_ATTRIB_0_POINTER + gl::MAX_VERTEX_ATTRIBS,
-
-        // Reserve bits for changes to VertexAttribFormat
-        DIRTY_BIT_ATTRIB_0_FORMAT   = DIRTY_BIT_ATTRIB_MAX_POINTER,
-        DIRTY_BIT_ATTRIB_MAX_FORMAT = DIRTY_BIT_ATTRIB_0_FORMAT + gl::MAX_VERTEX_ATTRIBS,
+        // Dirty bits for attributes.
+        DIRTY_BIT_ATTRIB_0,
+        DIRTY_BIT_ATTRIB_MAX = DIRTY_BIT_ATTRIB_0 + gl::MAX_VERTEX_ATTRIBS,
 
-        // Reserve bits for changes to VertexAttribBinding
-        DIRTY_BIT_ATTRIB_0_BINDING   = DIRTY_BIT_ATTRIB_MAX_FORMAT,
-        DIRTY_BIT_ATTRIB_MAX_BINDING = DIRTY_BIT_ATTRIB_0_BINDING + gl::MAX_VERTEX_ATTRIBS,
+        // Dirty bits for bindings.
+        DIRTY_BIT_BINDING_0   = DIRTY_BIT_ATTRIB_MAX,
+        DIRTY_BIT_BINDING_MAX = DIRTY_BIT_BINDING_0 + gl::MAX_VERTEX_ATTRIB_BINDINGS,
 
-        // Reserve bits for changes to BindVertexBuffer
-        DIRTY_BIT_BINDING_0_BUFFER   = DIRTY_BIT_ATTRIB_MAX_BINDING,
-        DIRTY_BIT_BINDING_MAX_BUFFER = DIRTY_BIT_BINDING_0_BUFFER + gl::MAX_VERTEX_ATTRIB_BINDINGS,
+        // We keep separate dirty bits for bound buffers whose data changed since last update.
+        DIRTY_BIT_BUFFER_DATA_0   = DIRTY_BIT_BINDING_MAX,
+        DIRTY_BIT_BUFFER_DATA_MAX = DIRTY_BIT_BUFFER_DATA_0 + gl::MAX_VERTEX_ATTRIB_BINDINGS,
 
-        // Reserve bits for binding divisors
-        DIRTY_BIT_BINDING_0_DIVISOR = DIRTY_BIT_BINDING_MAX_BUFFER,
-        DIRTY_BIT_BINDING_MAX_DIVISOR =
-            DIRTY_BIT_BINDING_0_DIVISOR + gl::MAX_VERTEX_ATTRIB_BINDINGS,
-
-        DIRTY_BIT_UNKNOWN = DIRTY_BIT_BINDING_MAX_DIVISOR,
+        DIRTY_BIT_UNKNOWN = DIRTY_BIT_BUFFER_DATA_MAX,
         DIRTY_BIT_MAX     = DIRTY_BIT_UNKNOWN,
     };
 
+    // We want to keep the number of dirty bits within 64 to keep iteration times fast.
+    static_assert(DIRTY_BIT_MAX <= 64, "Too many vertex array dirty bits.");
+
+    enum DirtyAttribBitType
+    {
+        DIRTY_ATTRIB_ENABLED,
+        DIRTY_ATTRIB_POINTER,
+        DIRTY_ATTRIB_FORMAT,
+        DIRTY_ATTRIB_BINDING,
+        DIRTY_ATTRIB_UNKNOWN,
+        DIRTY_ATTRIB_MAX = DIRTY_ATTRIB_UNKNOWN,
+    };
+
+    enum DirtyBindingBitType
+    {
+        DIRTY_BINDING_BUFFER,
+        DIRTY_BINDING_DIVISOR,
+        DIRTY_BINDING_UNKNOWN,
+        DIRTY_BINDING_MAX = DIRTY_BINDING_UNKNOWN,
+    };
+
     using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
+    using DirtyAttribBits       = angle::BitSet<DIRTY_ATTRIB_MAX>;
+    using DirtyBindingBits      = angle::BitSet<DIRTY_BINDING_MAX>;
+    using DirtyAttribBitsArray  = std::array<DirtyAttribBits, gl::MAX_VERTEX_ATTRIBS>;
+    using DirtyBindingBitsArray = std::array<DirtyBindingBits, gl::MAX_VERTEX_ATTRIB_BINDINGS>;
 
     static size_t GetVertexIndexFromDirtyBit(size_t dirtyBit);
 
-    void syncState(const Context *context);
+    gl::Error syncState(const Context *context);
     bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
 
     ComponentTypeMask getAttributesTypeMask() const { return mState.mVertexAttributesTypeMask; }
     AttributesMask getAttributesMask() const { return mState.mEnabledAttributesMask; }
 
+    void onBindingChanged(bool bound);
+
   private:
     ~VertexArray() override;
 
+    void setDirtyAttribBit(size_t attribIndex, DirtyAttribBitType dirtyAttribBit);
+    void setDirtyBindingBit(size_t bindingIndex, DirtyBindingBitType dirtyBindingBit);
+
+    void updateObserverBinding(size_t bindingIndex);
+    DirtyBitType getDirtyBitFromIndex(bool contentsChanged, angle::SubjectIndex index) const;
+
     GLuint mId;
 
     VertexArrayState mState;
     DirtyBits mDirtyBits;
+    DirtyAttribBitsArray mDirtyAttribBits;
+    DirtyBindingBitsArray mDirtyBindingBits;
+    Optional<DirtyBits> mDirtyBitsGuard;
 
     rx::VertexArrayImpl *mVertexArray;
+
+    std::vector<angle::ObserverBinding> mArrayBufferObserverBindings;
+    angle::ObserverBinding mElementArrayBufferObserverBinding;
 };
 
 }  // namespace gl
 
 #endif // LIBANGLE_VERTEXARRAY_H_
--- a/gfx/angle/checkout/src/libANGLE/VertexAttribute.cpp
+++ b/gfx/angle/checkout/src/libANGLE/VertexAttribute.cpp
@@ -33,16 +33,31 @@ VertexBinding &VertexBinding::operator=(
         mStride  = binding.mStride;
         mDivisor = binding.mDivisor;
         mOffset  = binding.mOffset;
         std::swap(binding.mBuffer, mBuffer);
     }
     return *this;
 }
 
+void VertexBinding::setBuffer(const gl::Context *context, Buffer *bufferIn, bool containerIsBound)
+{
+    if (mBuffer.get() && containerIsBound)
+        mBuffer->onBindingChanged(false, BufferBinding::Array);
+    mBuffer.set(context, bufferIn);
+    if (mBuffer.get() && containerIsBound)
+        mBuffer->onBindingChanged(true, BufferBinding::Array);
+}
+
+void VertexBinding::onContainerBindingChanged(bool bound)
+{
+    if (mBuffer.get())
+        mBuffer->onBindingChanged(bound, BufferBinding::Array);
+}
+
 VertexAttribute::VertexAttribute(GLuint bindingIndex)
     : enabled(false),
       type(GL_FLOAT),
       size(4u),
       normalized(false),
       pureInteger(false),
       pointer(nullptr),
       relativeOffset(0),
--- a/gfx/angle/checkout/src/libANGLE/VertexAttribute.h
+++ b/gfx/angle/checkout/src/libANGLE/VertexAttribute.h
@@ -32,17 +32,18 @@ class VertexBinding final : angle::NonCo
 
     GLuint getDivisor() const { return mDivisor; }
     void setDivisor(GLuint divisorIn) { mDivisor = divisorIn; }
 
     GLintptr getOffset() const { return mOffset; }
     void setOffset(GLintptr offsetIn) { mOffset = offsetIn; }
 
     const BindingPointer<Buffer> &getBuffer() const { return mBuffer; }
-    void setBuffer(const gl::Context *context, Buffer *bufferIn) { mBuffer.set(context, bufferIn); }
+    void setBuffer(const gl::Context *context, Buffer *bufferIn, bool containerIsBound);
+    void onContainerBindingChanged(bool bound);
 
   private:
     GLuint mStride;
     GLuint mDivisor;
     GLintptr mOffset;
 
     BindingPointer<Buffer> mBuffer;
 };
--- a/gfx/angle/checkout/src/libANGLE/angletypes.cpp
+++ b/gfx/angle/checkout/src/libANGLE/angletypes.cpp
@@ -146,23 +146,23 @@ SamplerState::SamplerState()
     compareMode   = GL_NONE;
     compareFunc   = GL_LEQUAL;
     sRGBDecode    = GL_DECODE_EXT;
 }
 
 SamplerState::SamplerState(const SamplerState &other) = default;
 
 // static
-SamplerState SamplerState::CreateDefaultForTarget(GLenum target)
+SamplerState SamplerState::CreateDefaultForTarget(TextureType type)
 {
     SamplerState state;
 
     // According to OES_EGL_image_external and ARB_texture_rectangle: For external textures, the
     // default min filter is GL_LINEAR and the default s and t wrap modes are GL_CLAMP_TO_EDGE.
-    if (target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ANGLE)
+    if (type == TextureType::External || type == TextureType::Rectangle)
     {
         state.minFilter = GL_LINEAR;
         state.wrapS     = GL_CLAMP_TO_EDGE;
         state.wrapT     = GL_CLAMP_TO_EDGE;
     }
 
     return state;
 }
@@ -306,17 +306,17 @@ void ComponentTypeMask::setIndex(GLenum 
 
 unsigned long ComponentTypeMask::to_ulong() const
 {
     return mTypeMask.to_ulong();
 }
 
 void ComponentTypeMask::from_ulong(unsigned long mask)
 {
-    mTypeMask = mask;
+    mTypeMask = angle::BitSet<MAX_COMPONENT_TYPE_MASK_INDEX * 2>(mask);
 }
 
 bool ComponentTypeMask::Validate(unsigned long outputTypes,
                                  unsigned long inputTypes,
                                  unsigned long outputMask,
                                  unsigned long inputMask)
 {
     static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS <= MAX_COMPONENT_TYPE_MASK_INDEX,
@@ -337,9 +337,38 @@ bool ComponentTypeMask::Validate(unsigne
 
     // To validate:
     // 1. Remove any indexes that are not enabled in the input (& inputMask)
     // 2. Remove any indexes that exist in output, but not in input (& outputMask)
     // 3. Use == to verify equality
     return (outputTypes & inputMask) == ((inputTypes & outputMask) & inputMask);
 }
 
+GLsizeiptr GetBoundBufferAvailableSize(const OffsetBindingPointer<Buffer> &binding)
+{
+    Buffer *buffer = binding.get();
+    if (buffer)
+    {
+        if (binding.getSize() == 0)
+            return static_cast<GLsizeiptr>(buffer->getSize());
+        angle::CheckedNumeric<GLintptr> offset       = binding.getOffset();
+        angle::CheckedNumeric<GLsizeiptr> size       = binding.getSize();
+        angle::CheckedNumeric<GLsizeiptr> bufferSize = buffer->getSize();
+        auto end                                     = offset + size;
+        auto clampedSize                             = size;
+        auto difference                              = end - bufferSize;
+        if (!difference.IsValid())
+        {
+            return 0;
+        }
+        if (difference.ValueOrDie() > 0)
+        {
+            clampedSize = size - difference;
+        }
+        return clampedSize.ValueOrDefault(0);
+    }
+    else
+    {
+        return 0;
+    }
+}
+
 }  // namespace gl
--- a/gfx/angle/checkout/src/libANGLE/angletypes.h
+++ b/gfx/angle/checkout/src/libANGLE/angletypes.h
@@ -4,17 +4,19 @@
 // found in the LICENSE file.
 //
 
 // angletypes.h : Defines a variety of structures and enum types that are used throughout libGLESv2
 
 #ifndef LIBANGLE_ANGLETYPES_H_
 #define LIBANGLE_ANGLETYPES_H_
 
+#include "common/Color.h"
 #include "common/bitset_utils.h"
+#include "common/vector_utils.h"
 #include "libANGLE/Constants.h"
 #include "libANGLE/Error.h"
 #include "libANGLE/PackedGLEnums.h"
 #include "libANGLE/RefCountObject.h"
 
 #include <stdint.h>
 
 #include <bitset>
@@ -35,29 +37,20 @@ enum PrimitiveType
     PRIMITIVE_TRIANGLES,
     PRIMITIVE_TRIANGLE_STRIP,
     PRIMITIVE_TRIANGLE_FAN,
     PRIMITIVE_TYPE_MAX,
 };
 
 PrimitiveType GetPrimitiveType(GLenum drawMode);
 
-enum ShaderType
-{
-    SHADER_VERTEX,
-    SHADER_FRAGMENT,
-    SHADER_GEOMETRY,
-    SHADER_COMPUTE,
-    SHADER_TYPE_MAX
-};
-
 struct Rectangle
 {
     Rectangle() : x(0), y(0), width(0), height(0) {}
-    Rectangle(int x_in, int y_in, int width_in, int height_in)
+    constexpr Rectangle(int x_in, int y_in, int width_in, int height_in)
         : x(x_in), y(y_in), width(width_in), height(height_in)
     {
     }
 
     int x0() const { return x; }
     int y0() const { return y; }
     int x1() const { return x + width; }
     int y1() const { return y + height; }
@@ -70,59 +63,70 @@ struct Rectangle
 
 bool operator==(const Rectangle &a, const Rectangle &b);
 bool operator!=(const Rectangle &a, const Rectangle &b);
 
 bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection);
 
 struct Offset
 {
+    Offset() : x(0), y(0), z(0) {}
+    Offset(int x_in, int y_in, int z_in) : x(x_in), y(y_in), z(z_in) {}
+
     int x;
     int y;
     int z;
-
-    Offset() : x(0), y(0), z(0) { }
-    Offset(int x_in, int y_in, int z_in) : x(x_in), y(y_in), z(z_in) { }
 };
 
 bool operator==(const Offset &a, const Offset &b);
 bool operator!=(const Offset &a, const Offset &b);
 
 struct Extents
 {
-    int width;
-    int height;
-    int depth;
-
-    Extents() : width(0), height(0), depth(0) { }
-    Extents(int width_, int height_, int depth_) : width(width_), height(height_), depth(depth_) { }
+    Extents() : width(0), height(0), depth(0) {}
+    Extents(int width_, int height_, int depth_) : width(width_), height(height_), depth(depth_) {}
 
     Extents(const Extents &other) = default;
     Extents &operator=(const Extents &other) = default;
 
     bool empty() const { return (width * height * depth) == 0; }
+
+    int width;
+    int height;
+    int depth;
 };
 
 bool operator==(const Extents &lhs, const Extents &rhs);
 bool operator!=(const Extents &lhs, const Extents &rhs);
 
 struct Box
 {
+    Box() : x(0), y(0), z(0), width(0), height(0), depth(0) {}
+    Box(int x_in, int y_in, int z_in, int width_in, int height_in, int depth_in)
+        : x(x_in), y(y_in), z(z_in), width(width_in), height(height_in), depth(depth_in)
+    {
+    }
+    Box(const Offset &offset, const Extents &size)
+        : x(offset.x),
+          y(offset.y),
+          z(offset.z),
+          width(size.width),
+          height(size.height),
+          depth(size.depth)
+    {
+    }
+    bool operator==(const Box &other) const;
+    bool operator!=(const Box &other) const;
+
     int x;
     int y;
     int z;
     int width;
     int height;
     int depth;
-
-    Box() : x(0), y(0), z(0), width(0), height(0), depth(0) { }
-    Box(int x_in, int y_in, int z_in, int width_in, int height_in, int depth_in) : x(x_in), y(y_in), z(z_in), width(width_in), height(height_in), depth(depth_in) { }
-    Box(const Offset &offset, const Extents &size) : x(offset.x), y(offset.y), z(offset.z), width(size.width), height(size.height), depth(size.depth) { }
-    bool operator==(const Box &other) const;
-    bool operator!=(const Box &other) const;
 };
 
 struct RasterizerState final
 {
     // This will zero-initialize the struct, including padding.
     RasterizerState();
 
     bool cullFace;
@@ -199,17 +203,17 @@ bool operator!=(const DepthStencilState 
 
 // State from Table 6.10 (state per sampler object)
 struct SamplerState final
 {
     // This will zero-initialize the struct, including padding.
     SamplerState();
     SamplerState(const SamplerState &other);
 
-    static SamplerState CreateDefaultForTarget(GLenum target);
+    static SamplerState CreateDefaultForTarget(TextureType type);
 
     GLenum minFilter;
     GLenum magFilter;
 
     GLenum wrapS;
     GLenum wrapT;
     GLenum wrapR;
 
@@ -311,60 +315,67 @@ struct ComponentTypeMask final
     // Each index type is represented by 2 bits
     angle::BitSet<MAX_COMPONENT_TYPE_MASK_INDEX * 2> mTypeMask;
 };
 
 using ContextID = uintptr_t;
 
 constexpr size_t CUBE_FACE_COUNT = 6;
 
-using TextureMap = std::map<GLenum, BindingPointer<Texture>>;
+using TextureMap = angle::PackedEnumMap<TextureType, BindingPointer<Texture>>;
 
 template <typename T>
 using AttachmentArray = std::array<T, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS>;
 
 template <typename T>
 using DrawBuffersArray = std::array<T, IMPLEMENTATION_MAX_DRAW_BUFFERS>;
 
 template <typename T>
 using AttribArray = std::array<T, MAX_VERTEX_ATTRIBS>;
 
+// OffsetBindingPointer.getSize() returns the size specified by the user, which may be larger than
+// the size of the bound buffer. This function reduces the returned size to fit the bound buffer if
+// necessary. Returns 0 if no buffer is bound or if integer overflow occurs.
+GLsizeiptr GetBoundBufferAvailableSize(const OffsetBindingPointer<Buffer> &binding);
+
 }  // namespace gl
 
 namespace rx
 {
 // A macro that determines whether an object has a given runtime type.
 #if defined(__clang__)
 #if __has_feature(cxx_rtti)
 #define ANGLE_HAS_DYNAMIC_CAST 1
 #endif
-#elif !defined(NDEBUG) && (!defined(_MSC_VER) || defined(_CPPRTTI)) && (!defined(__GNUC__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) || defined(__GXX_RTTI))
+#elif !defined(NDEBUG) && (!defined(_MSC_VER) || defined(_CPPRTTI)) &&              \
+    (!defined(__GNUC__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) || \
+     defined(__GXX_RTTI))
 #define ANGLE_HAS_DYNAMIC_CAST 1
 #endif
 
 #ifdef ANGLE_HAS_DYNAMIC_CAST
-#define ANGLE_HAS_DYNAMIC_TYPE(type, obj) (dynamic_cast<type >(obj) != nullptr)
+#define ANGLE_HAS_DYNAMIC_TYPE(type, obj) (dynamic_cast<type>(obj) != nullptr)
 #undef ANGLE_HAS_DYNAMIC_CAST
 #else
 #define ANGLE_HAS_DYNAMIC_TYPE(type, obj) (obj != nullptr)
 #endif
 
 // Downcast a base implementation object (EG TextureImpl to TextureD3D)
 template <typename DestT, typename SrcT>
 inline DestT *GetAs(SrcT *src)
 {
-    ASSERT(ANGLE_HAS_DYNAMIC_TYPE(DestT*, src));
-    return static_cast<DestT*>(src);
+    ASSERT(ANGLE_HAS_DYNAMIC_TYPE(DestT *, src));
+    return static_cast<DestT *>(src);
 }
 
 template <typename DestT, typename SrcT>
 inline const DestT *GetAs(const SrcT *src)
 {
-    ASSERT(ANGLE_HAS_DYNAMIC_TYPE(const DestT*, src));
-    return static_cast<const DestT*>(src);
+    ASSERT(ANGLE_HAS_DYNAMIC_TYPE(const DestT *, src));
+    return static_cast<const DestT *>(src);
 }
 
 #undef ANGLE_HAS_DYNAMIC_TYPE
 
 // Downcast a GL object to an Impl (EG gl::Texture to rx::TextureD3D)
 template <typename DestT, typename SrcT>
 inline DestT *GetImplAs(SrcT *src)
 {
@@ -496,9 +507,9 @@ using UniqueObjectPointer = UniqueObject
 }  // namespace angle
 
 namespace gl
 {
 class ContextState;
 
 }  // namespace gl
 
-#endif // LIBANGLE_ANGLETYPES_H_
+#endif  // LIBANGLE_ANGLETYPES_H_
--- a/gfx/angle/checkout/src/libANGLE/entry_points_enum_autogen.h
+++ b/gfx/angle/checkout/src/libANGLE/entry_points_enum_autogen.h
@@ -24,35 +24,38 @@ enum class EntryPoint
     BeginQuery,
     BeginQueryEXT,
     BeginTransformFeedback,
     BindAttribLocation,
     BindBuffer,
     BindBufferBase,
     BindBufferRange,
     BindFramebuffer,
+    BindFramebufferOES,
     BindImageTexture,
     BindProgramPipeline,
     BindRenderbuffer,
+    BindRenderbufferOES,
     BindSampler,
     BindTexture,
     BindTransformFeedback,
     BindVertexArray,
     BindVertexArrayOES,
     BindVertexBuffer,
     BlendColor,
     BlendEquation,
     BlendEquationSeparate,
     BlendFunc,
     BlendFuncSeparate,
     BlitFramebuffer,
     BlitFramebufferANGLE,
     BufferData,
     BufferSubData,
     CheckFramebufferStatus,
+    CheckFramebufferStatusOES,
     Clear,
     ClearBufferfi,
     ClearBufferfv,
     ClearBufferiv,
     ClearBufferuiv,
     ClearColor,
     ClearColorx,
     ClearDepthf,
@@ -82,21 +85,23 @@ enum class EntryPoint
     CullFace,
     CurrentPaletteMatrixOES,
     DebugMessageCallbackKHR,
     DebugMessageControlKHR,
     DebugMessageInsertKHR,
     DeleteBuffers,
     DeleteFencesNV,
     DeleteFramebuffers,
+    DeleteFramebuffersOES,
     DeleteProgram,
     DeleteProgramPipelines,
     DeleteQueries,
     DeleteQueriesEXT,
     DeleteRenderbuffers,
+    DeleteRenderbuffersOES,
     DeleteSamplers,
     DeleteShader,
     DeleteSync,
     DeleteTextures,
     DeleteTransformFeedbacks,
     DeleteVertexArrays,
     DeleteVertexArraysOES,
     DepthFunc,
@@ -144,34 +149,39 @@ enum class EntryPoint
     FlushMappedBufferRange,
     FlushMappedBufferRangeEXT,
     Fogf,
     Fogfv,
     Fogx,
     Fogxv,
     FramebufferParameteri,
     FramebufferRenderbuffer,
+    FramebufferRenderbufferOES,
     FramebufferTexture2D,
+    FramebufferTexture2DOES,
     FramebufferTextureLayer,
     FrontFace,
     Frustumf,
     Frustumx,
     GenBuffers,
     GenFencesNV,
     GenFramebuffers,
+    GenFramebuffersOES,
     GenProgramPipelines,
     GenQueries,
     GenQueriesEXT,
     GenRenderbuffers,
+    GenRenderbuffersOES,
     GenSamplers,
     GenTextures,
     GenTransformFeedbacks,
     GenVertexArrays,
     GenVertexArraysOES,
     GenerateMipmap,
+    GenerateMipmapOES,
     GetActiveAttrib,
     GetActiveUniform,
     GetActiveUniformBlockName,
     GetActiveUniformBlockiv,
     GetActiveUniformsiv,
     GetAttachedShaders,
     GetAttribLocation,
     GetBooleani_v,
@@ -184,16 +194,17 @@ enum class EntryPoint
     GetClipPlanex,
     GetDebugMessageLogKHR,
     GetError,
     GetFenceivNV,
     GetFixedv,
     GetFloatv,
     GetFragDataLocation,
     GetFramebufferAttachmentParameteriv,
+    GetFramebufferAttachmentParameterivOES,
     GetFramebufferParameteriv,
     GetGraphicsResetStatusEXT,
     GetInteger64i_v,
     GetInteger64v,
     GetIntegeri_v,
     GetIntegerv,
     GetInternalformativ,
     GetLightfv,
@@ -219,28 +230,32 @@ enum class EntryPoint
     GetQueryObjecti64vEXT,
     GetQueryObjectivEXT,
     GetQueryObjectui64vEXT,
     GetQueryObjectuiv,
     GetQueryObjectuivEXT,
     GetQueryiv,
     GetQueryivEXT,
     GetRenderbufferParameteriv,
+    GetRenderbufferParameterivOES,
     GetSamplerParameterfv,
     GetSamplerParameteriv,
     GetShaderInfoLog,
     GetShaderPrecisionFormat,
     GetShaderSource,
     GetShaderiv,
     GetString,
     GetStringi,
     GetSynciv,
     GetTexEnvfv,
     GetTexEnviv,
     GetTexEnvxv,
+    GetTexGenfvOES,
+    GetTexGenivOES,
+    GetTexGenxvOES,
     GetTexLevelParameterfv,
     GetTexLevelParameteriv,
     GetTexParameterfv,
     GetTexParameteriv,
     GetTexParameterxv,
     GetTransformFeedbackVarying,
     GetTranslatedShaderSourceANGLE,
     GetUniformBlockIndex,
@@ -259,21 +274,23 @@ enum class EntryPoint
     Hint,
     InsertEventMarkerEXT,
     InvalidateFramebuffer,
     InvalidateSubFramebuffer,
     IsBuffer,
     IsEnabled,
     IsFenceNV,
     IsFramebuffer,
+    IsFramebufferOES,
     IsProgram,
     IsProgramPipeline,
     IsQuery,
     IsQueryEXT,
     IsRenderbuffer,
+    IsRenderbufferOES,
     IsSampler,
     IsShader,
     IsSync,
     IsTexture,
     IsTransformFeedback,
     IsVertexArray,
     IsVertexArrayOES,
     LightModelf,
@@ -371,16 +388,17 @@ enum class EntryPoint
     QueryMatrixxOES,
     ReadBuffer,
     ReadPixels,
     ReadnPixelsEXT,
     ReleaseShaderCompiler,
     RenderbufferStorage,
     RenderbufferStorageMultisample,
     RenderbufferStorageMultisampleANGLE,
+    RenderbufferStorageOES,
     ResumeTransformFeedback,
     Rotatef,
     Rotatex,
     SampleCoverage,
     SampleCoveragex,
     SampleMaski,
     SamplerParameterf,
     SamplerParameterfv,
@@ -402,16 +420,22 @@ enum class EntryPoint
     TestFenceNV,
     TexCoordPointer,
     TexEnvf,
     TexEnvfv,
     TexEnvi,
     TexEnviv,
     TexEnvx,
     TexEnvxv,
+    TexGenfOES,
+    TexGenfvOES,
+    TexGeniOES,
+    TexGenivOES,
+    TexGenxOES,
+    TexGenxvOES,
     TexImage2D,
     TexImage3D,
     TexParameterf,
     TexParameterfv,
     TexParameteri,
     TexParameteriv,
     TexParameterx,
     TexParameterxv,
--- a/gfx/angle/checkout/src/libANGLE/es3_copy_conversion_table_autogen.cpp
+++ b/gfx/angle/checkout/src/libANGLE/es3_copy_conversion_table_autogen.cpp
@@ -1,12 +1,12 @@
 // GENERATED FILE - DO NOT EDIT.
 // Generated by gen_copy_conversion_table.py using data from es3_copy_conversion_formats.json.
 //
-// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
 // format_map:
 //   Determining the sized internal format from a (format,type) pair.
 //   Also check es3 format combinations for validity.
 
 #include "angle_gl.h"
--- a/gfx/angle/checkout/src/libANGLE/format_map_autogen.cpp
+++ b/gfx/angle/checkout/src/libANGLE/format_map_autogen.cpp
@@ -1,13 +1,13 @@
 // GENERATED FILE - DO NOT EDIT.
 // Generated by gen_format_map.py using data from format_map_data.json.
 // ES3 format info from es3_format_type_combinations.json.
 //
-// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
 // format_map:
 //   Determining the sized internal format from a (format,type) pair.
 //   Also check es3 format combinations for validity.
 
 #include "angle_gl.h"
--- a/gfx/angle/checkout/src/libANGLE/formatutils.cpp
+++ b/gfx/angle/checkout/src/libANGLE/formatutils.cpp
@@ -669,19 +669,19 @@ static InternalFormatInfoMap BuildIntern
 
     //                 | Internal format    |sized| R | G | B | A |S | Format         | Type                           | Component type        | SRGB | Texture supported                           | Renderable                                  | Filterable    |
     AddRGBAFormat(&map, GL_R8,               true,  8,  0,  0,  0, 0, GL_RED,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureRG>, RequireESOrExt<3, 0, &Extensions::textureRG>, AlwaysSupported);
     AddRGBAFormat(&map, GL_R8_SNORM,         true,  8,  0,  0,  0, 0, GL_RED,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireES<3, 0>,                              NeverSupported,                               AlwaysSupported);
     AddRGBAFormat(&map, GL_RG8,              true,  8,  8,  0,  0, 0, GL_RG,           GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureRG>, RequireESOrExt<3, 0, &Extensions::textureRG>, AlwaysSupported);
     AddRGBAFormat(&map, GL_RG8_SNORM,        true,  8,  8,  0,  0, 0, GL_RG,           GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireES<3, 0>,                              NeverSupported,                               AlwaysSupported);
     AddRGBAFormat(&map, GL_RGB8,             true,  8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::rgb8rgba8>, RequireESOrExt<3, 0, &Extensions::rgb8rgba8>, AlwaysSupported);
     AddRGBAFormat(&map, GL_RGB8_SNORM,       true,  8,  8,  8,  0, 0, GL_RGB,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireES<3, 0>,                              NeverSupported,                               AlwaysSupported);
-    AddRGBAFormat(&map, GL_RGB565,           true,  5,  6,  5,  0, 0, GL_RGB,          GL_UNSIGNED_SHORT_5_6_5,         GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>,                              RequireES<2, 0>,                              AlwaysSupported);
-    AddRGBAFormat(&map, GL_RGBA4,            true,  4,  4,  4,  4, 0, GL_RGBA,         GL_UNSIGNED_SHORT_4_4_4_4,       GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>,                              RequireES<2, 0>,                              AlwaysSupported);
-    AddRGBAFormat(&map, GL_RGB5_A1,          true,  5,  5,  5,  1, 0, GL_RGBA,         GL_UNSIGNED_SHORT_5_5_5_1,       GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>,                              RequireES<2, 0>,                              AlwaysSupported);
+    AddRGBAFormat(&map, GL_RGB565,           true,  5,  6,  5,  0, 0, GL_RGB,          GL_UNSIGNED_SHORT_5_6_5,         GL_UNSIGNED_NORMALIZED, false, RequireES<1, 0>,                              RequireES<1, 0>,                              AlwaysSupported);
+    AddRGBAFormat(&map, GL_RGBA4,            true,  4,  4,  4,  4, 0, GL_RGBA,         GL_UNSIGNED_SHORT_4_4_4_4,       GL_UNSIGNED_NORMALIZED, false, RequireES<1, 0>,                              RequireES<1, 0>,                              AlwaysSupported);
+    AddRGBAFormat(&map, GL_RGB5_A1,          true,  5,  5,  5,  1, 0, GL_RGBA,         GL_UNSIGNED_SHORT_5_5_5_1,       GL_UNSIGNED_NORMALIZED, false, RequireES<1, 0>,                              RequireES<1, 0>,                              AlwaysSupported);
     AddRGBAFormat(&map, GL_RGBA8,            true,  8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::rgb8rgba8>, RequireESOrExt<3, 0, &Extensions::rgb8rgba8>, AlwaysSupported);
     AddRGBAFormat(&map, GL_RGBA8_SNORM,      true,  8,  8,  8,  8, 0, GL_RGBA,         GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireES<3, 0>,                              NeverSupported,                               AlwaysSupported);
     AddRGBAFormat(&map, GL_RGB10_A2,         true, 10, 10, 10,  2, 0, GL_RGBA,         GL_UNSIGNED_INT_2_10_10_10_REV,  GL_UNSIGNED_NORMALIZED, false, RequireES<3, 0>,                              RequireES<3, 0>,                              AlwaysSupported);
     AddRGBAFormat(&map, GL_RGB10_A2UI,       true, 10, 10, 10,  2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV,  GL_UNSIGNED_INT,        false, RequireES<3, 0>,                              RequireES<3, 0>,                              NeverSupported);
     AddRGBAFormat(&map, GL_SRGB8,            true,  8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  RequireESOrExt<3, 0, &Extensions::sRGB>,      NeverSupported,                               AlwaysSupported);
     AddRGBAFormat(&map, GL_SRGB8_ALPHA8,     true,  8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  RequireESOrExt<3, 0, &Extensions::sRGB>,      RequireESOrExt<3, 0, &Extensions::sRGB>,      AlwaysSupported);
     AddRGBAFormat(&map, GL_RGB9_E5,          true,  9,  9,  9,  0, 5, GL_RGB,          GL_UNSIGNED_INT_5_9_9_9_REV,     GL_FLOAT,               false, RequireES<3, 0>,                              NeverSupported,                               AlwaysSupported);
     AddRGBAFormat(&map, GL_R8I,              true,  8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_BYTE,                         GL_INT,                 false, RequireES<3, 0>,                              RequireES<3, 0>,                              NeverSupported);
@@ -732,17 +732,17 @@ static InternalFormatInfoMap BuildIntern
     AddRGBAFormat(&map, GL_RGBA16F,          true, 16, 16, 16, 16, 0, GL_RGBA,         GL_HALF_FLOAT,                   GL_FLOAT, false, HalfFloatSupport,   HalfFloatRGBARenderableSupport, RequireESOrExt<3, 0, &Extensions::textureHalfFloatLinear>);
     AddRGBAFormat(&map, GL_R32F,             true, 32,  0,  0,  0, 0, GL_RED,          GL_FLOAT,                        GL_FLOAT, false, FloatRGSupport,     FloatRGRenderableSupport,       RequireExt<&Extensions::textureFloatLinear>              );
     AddRGBAFormat(&map, GL_RG32F,            true, 32, 32,  0,  0, 0, GL_RG,           GL_FLOAT,                        GL_FLOAT, false, FloatRGSupport,     FloatRGRenderableSupport,       RequireExt<&Extensions::textureFloatLinear>              );
     AddRGBAFormat(&map, GL_RGB32F,           true, 32, 32, 32,  0, 0, GL_RGB,          GL_FLOAT,                        GL_FLOAT, false, FloatSupport,       FloatRGBRenderableSupport,      RequireExt<&Extensions::textureFloatLinear>              );
     AddRGBAFormat(&map, GL_RGBA32F,          true, 32, 32, 32, 32, 0, GL_RGBA,         GL_FLOAT,                        GL_FLOAT, false, FloatSupport,       FloatRGBARenderableSupport,     RequireExt<&Extensions::textureFloatLinear>              );
 
     // Depth stencil formats
     //                         | Internal format         |sized| D |S | X | Format            | Type                             | Component type        | Supported                                       | Renderable                                                                            | Filterable                                  |
-    AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT16,     true, 16, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,                 GL_UNSIGNED_NORMALIZED, RequireES<2, 0>,                                  RequireES<2, 0>,                                                                        RequireESOrExt<3, 0, &Extensions::depthTextures>);
+    AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT16,     true, 16, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,                 GL_UNSIGNED_NORMALIZED, RequireES<1, 0>,                                  RequireES<1, 0>,                                                                        RequireESOrExt<3, 0, &Extensions::depthTextures>);
     AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT24,     true, 24, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, RequireES<3, 0>,                                  RequireES<3, 0>,                                                                        RequireESOrExt<3, 0, &Extensions::depthTextures>);
     AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT32F,    true, 32, 0,  0, GL_DEPTH_COMPONENT, GL_FLOAT,                          GL_FLOAT,               RequireES<3, 0>,                                  RequireES<3, 0>,                                                                        RequireESOrExt<3, 0, &Extensions::depthTextures>);
     AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT32_OES, true, 32, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, RequireExtOrExt<&Extensions::depthTextures, &Extensions::depth32>, RequireExtOrExt<&Extensions::depthTextures, &Extensions::depth32>,     AlwaysSupported                                 );
     AddDepthStencilFormat(&map, GL_DEPTH24_STENCIL8,      true, 24, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8,              GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, 0, &Extensions::depthTextures>, RequireESOrExtOrExt<3, 0, &Extensions::depthTextures, &Extensions::packedDepthStencil>, AlwaysSupported                                 );
     AddDepthStencilFormat(&map, GL_DEPTH32F_STENCIL8,     true, 32, 8, 24, GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT,               RequireES<3, 0>,                                  RequireES<3, 0>,                                                                        AlwaysSupported                                 );
     // STENCIL_INDEX8 is special-cased, see around the bottom of the list.
 
     // Luminance alpha formats
@@ -823,17 +823,17 @@ static InternalFormatInfoMap BuildIntern
     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, 12, 10, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true,  RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported);
     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, 12, 12, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true,  RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported);
 
     // For STENCIL_INDEX8 we chose a normalized component type for the following reasons:
     // - Multisampled buffer are disallowed for non-normalized integer component types and we want to support it for STENCIL_INDEX8
     // - All other stencil formats (all depth-stencil) are either float or normalized
     // - It affects only validation of internalformat in RenderbufferStorageMultisample.
     //                         | Internal format  |sized|D |S |X | Format    | Type            | Component type        | Supported      | Renderable     | Filterable   |
-    AddDepthStencilFormat(&map, GL_STENCIL_INDEX8, true, 0, 8, 0, GL_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<2, 0>, RequireES<2, 0>, NeverSupported);
+    AddDepthStencilFormat(&map, GL_STENCIL_INDEX8, true, 0, 8, 0, GL_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<1, 0>, RequireES<1, 0>, NeverSupported);
 
     // From GL_ANGLE_lossy_etc_decode
     //                       | Internal format                                                |W |H |BS |CC| Format | Type            | SRGB | Supported                                                                                     | Renderable     | Filterable    |
     AddCompressedFormat(&map, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE,                                 4, 4, 64, 3, GL_RGB,  GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::lossyETCDecode>, NeverSupported, AlwaysSupported);
     AddCompressedFormat(&map, GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE,                      4, 4, 64, 3, GL_RGB,  GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::lossyETCDecode>, NeverSupported, AlwaysSupported);
     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE,                     4, 4, 64, 3, GL_RGB,  GL_UNSIGNED_BYTE, true,  RequireExt<&Extensions::lossyETCDecode>, NeverSupported, AlwaysSupported);
     AddCompressedFormat(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE,  4, 4, 64, 3, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::lossyETCDecode>, NeverSupported, AlwaysSupported);
     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE, 4, 4, 64, 3, GL_RGBA, GL_UNSIGNED_BYTE, true,  RequireExt<&Extensions::lossyETCDecode>, NeverSupported, AlwaysSupported);
@@ -850,23 +850,23 @@ static InternalFormatInfoMap BuildIntern
     AddRGBAFormat(&map, GL_RGBA16_SNORM_EXT, true, 16, 16, 16, 16, 0, GL_RGBA,         GL_SHORT,                        GL_SIGNED_NORMALIZED,   false, RequireExt<&Extensions::textureNorm16>,    NeverSupported,                            AlwaysSupported);
 
     // Unsized formats
     //                 | Internal format    |sized | R | G | B | A |S | Format         | Type                           | Component type        | SRGB | Texture supported                           | Renderable                                  | Filterable    |
     AddRGBAFormat(&map, GL_RED,              false,  8,  0,  0,  0, 0, GL_RED,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureRG>,           AlwaysSupported,                              AlwaysSupported);
     AddRGBAFormat(&map, GL_RED,              false,  8,  0,  0,  0, 0, GL_RED,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,                               NeverSupported,                               NeverSupported );
     AddRGBAFormat(&map, GL_RG,               false,  8,  8,  0,  0, 0, GL_RG,           GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureRG>,           AlwaysSupported,                              AlwaysSupported);
     AddRGBAFormat(&map, GL_RG,               false,  8,  8,  0,  0, 0, GL_RG,           GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,                               NeverSupported,                               NeverSupported );
-    AddRGBAFormat(&map, GL_RGB,              false,  8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>,                              AlwaysSupported,                              AlwaysSupported);
-    AddRGBAFormat(&map, GL_RGB,              false,  5,  6,  5,  0, 0, GL_RGB,          GL_UNSIGNED_SHORT_5_6_5,         GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>,                              RequireES<2, 0>,                              AlwaysSupported);
+    AddRGBAFormat(&map, GL_RGB,              false,  8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireES<1, 0>,                              AlwaysSupported,                              AlwaysSupported);
+    AddRGBAFormat(&map, GL_RGB,              false,  5,  6,  5,  0, 0, GL_RGB,          GL_UNSIGNED_SHORT_5_6_5,         GL_UNSIGNED_NORMALIZED, false, RequireES<1, 0>,                              RequireES<1, 0>,                              AlwaysSupported);
     AddRGBAFormat(&map, GL_RGB,              false,  8,  8,  8,  0, 0, GL_RGB,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,                               NeverSupported,                               NeverSupported );
-    AddRGBAFormat(&map, GL_RGBA,             false,  4,  4,  4,  4, 0, GL_RGBA,         GL_UNSIGNED_SHORT_4_4_4_4,       GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>,                              RequireES<2, 0>,                              AlwaysSupported);
-    AddRGBAFormat(&map, GL_RGBA,             false,  5,  5,  5,  1, 0, GL_RGBA,         GL_UNSIGNED_SHORT_5_5_5_1,       GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>,                              RequireES<2, 0>,                              AlwaysSupported);
-    AddRGBAFormat(&map, GL_RGBA,             false,  8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>,                              RequireES<2, 0>,                              AlwaysSupported);
-    AddRGBAFormat(&map, GL_RGBA,             false, 10, 10, 10,  2, 0, GL_RGBA,         GL_UNSIGNED_INT_2_10_10_10_REV,  GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>,                              RequireES<2, 0>,                              AlwaysSupported);
+    AddRGBAFormat(&map, GL_RGBA,             false,  4,  4,  4,  4, 0, GL_RGBA,         GL_UNSIGNED_SHORT_4_4_4_4,       GL_UNSIGNED_NORMALIZED, false, RequireES<1, 0>,                              RequireES<1, 0>,                              AlwaysSupported);
+    AddRGBAFormat(&map, GL_RGBA,             false,  5,  5,  5,  1, 0, GL_RGBA,         GL_UNSIGNED_SHORT_5_5_5_1,       GL_UNSIGNED_NORMALIZED, false, RequireES<1, 0>,                              RequireES<1, 0>,                              AlwaysSupported);
+    AddRGBAFormat(&map, GL_RGBA,             false,  8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireES<1, 0>,                              RequireES<1, 0>,                              AlwaysSupported);
+    AddRGBAFormat(&map, GL_RGBA,             false, 10, 10, 10,  2, 0, GL_RGBA,         GL_UNSIGNED_INT_2_10_10_10_REV,  GL_UNSIGNED_NORMALIZED, false, RequireES<1, 0>,                              RequireES<1, 0>,                              AlwaysSupported);
     AddRGBAFormat(&map, GL_RGBA,             false,  8,  8,  8,  8, 0, GL_RGBA,         GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,                               NeverSupported,                               NeverSupported );
     AddRGBAFormat(&map, GL_SRGB,             false,  8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  RequireExt<&Extensions::sRGB>,                NeverSupported,                               AlwaysSupported);
     AddRGBAFormat(&map, GL_SRGB_ALPHA_EXT,   false,  8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  RequireExt<&Extensions::sRGB>,                RequireExt<&Extensions::sRGB>,                AlwaysSupported);
 
     AddRGBAFormat(&map, GL_BGRA_EXT,         false,  8,  8,  8,  8, 0, GL_BGRA_EXT,     GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported);
 
     // Unsized integer formats
     //                 |Internal format |sized | R | G | B | A |S | Format         | Type                          | Component type | SRGB | Texture        | Renderable    | Filterable   |
@@ -910,34 +910,34 @@ static InternalFormatInfoMap BuildIntern
     AddRGBAFormat(&map, GL_RG,           false, 32, 32,  0,  0, 0, GL_RG,           GL_FLOAT,                        GL_FLOAT, false, UnsizedFloatRGSupport,        UnsizedFloatRGRenderableSupport,        RequireExt<&Extensions::textureFloatLinear>              );
     AddRGBAFormat(&map, GL_RGB,          false, 32, 32, 32,  0, 0, GL_RGB,          GL_FLOAT,                        GL_FLOAT, false, UnsizedFloatSupport,          UnsizedFloatRGBRenderableSupport,       RequireExt<&Extensions::textureFloatLinear>              );
     AddRGBAFormat(&map, GL_RGB,          false,  9,  9,  9,  0, 5, GL_RGB,          GL_UNSIGNED_INT_5_9_9_9_REV,     GL_FLOAT, false, NeverSupported,               NeverSupported,                         NeverSupported                                           );
     AddRGBAFormat(&map, GL_RGB,          false, 11, 11, 10,  0, 0, GL_RGB,          GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, NeverSupported,               NeverSupported,                         NeverSupported                                           );
     AddRGBAFormat(&map, GL_RGBA,         false, 32, 32, 32, 32, 0, GL_RGBA,         GL_FLOAT,                        GL_FLOAT, false, UnsizedFloatSupport,          UnsizedFloatRGBARenderableSupport,      RequireExt<&Extensions::textureFloatLinear>              );
 
     // Unsized luminance alpha formats
     //                | Internal format    |sized | L | A | Format            | Type             | Component type        | Supported                                | Renderable    | Filterable                                    |
-    AddLUMAFormat(&map, GL_ALPHA,           false,  0,  8, GL_ALPHA,           GL_UNSIGNED_BYTE,  GL_UNSIGNED_NORMALIZED, RequireES<2, 0>,                           NeverSupported, AlwaysSupported                                );
-    AddLUMAFormat(&map, GL_LUMINANCE,       false,  8,  0, GL_LUMINANCE,       GL_UNSIGNED_BYTE,  GL_UNSIGNED_NORMALIZED, RequireES<2, 0>,                           NeverSupported, AlwaysSupported                                );
-    AddLUMAFormat(&map, GL_LUMINANCE_ALPHA, false,  8,  8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,  GL_UNSIGNED_NORMALIZED, RequireES<2, 0>,                           NeverSupported, AlwaysSupported                                );
+    AddLUMAFormat(&map, GL_ALPHA,           false,  0,  8, GL_ALPHA,           GL_UNSIGNED_BYTE,  GL_UNSIGNED_NORMALIZED, RequireES<1, 0>,                           NeverSupported, AlwaysSupported                                );
+    AddLUMAFormat(&map, GL_LUMINANCE,       false,  8,  0, GL_LUMINANCE,       GL_UNSIGNED_BYTE,  GL_UNSIGNED_NORMALIZED, RequireES<1, 0>,                           NeverSupported, AlwaysSupported                                );
+    AddLUMAFormat(&map, GL_LUMINANCE_ALPHA, false,  8,  8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,  GL_UNSIGNED_NORMALIZED, RequireES<1, 0>,                           NeverSupported, AlwaysSupported                                );
     AddLUMAFormat(&map, GL_ALPHA,           false,  0, 16, GL_ALPHA,           GL_HALF_FLOAT_OES, GL_FLOAT,               RequireExt<&Extensions::textureHalfFloat>, NeverSupported, RequireExt<&Extensions::textureHalfFloatLinear>);
     AddLUMAFormat(&map, GL_LUMINANCE,       false, 16,  0, GL_LUMINANCE,       GL_HALF_FLOAT_OES, GL_FLOAT,               RequireExt<&Extensions::textureHalfFloat>, NeverSupported, RequireExt<&Extensions::textureHalfFloatLinear>);
     AddLUMAFormat(&map, GL_LUMINANCE_ALPHA ,false, 16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_FLOAT,               RequireExt<&Extensions::textureHalfFloat>, NeverSupported, RequireExt<&Extensions::textureHalfFloatLinear>);
     AddLUMAFormat(&map, GL_ALPHA,           false,  0, 32, GL_ALPHA,           GL_FLOAT,          GL_FLOAT,               RequireExt<&Extensions::textureFloat>,     NeverSupported, RequireExt<&Extensions::textureFloatLinear>    );
     AddLUMAFormat(&map, GL_LUMINANCE,       false, 32,  0, GL_LUMINANCE,       GL_FLOAT,          GL_FLOAT,               RequireExt<&Extensions::textureFloat>,     NeverSupported, RequireExt<&Extensions::textureFloatLinear>    );
     AddLUMAFormat(&map, GL_LUMINANCE_ALPHA, false, 32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT,          GL_FLOAT,               RequireExt<&Extensions::textureFloat>,     NeverSupported, RequireExt<&Extensions::textureFloatLinear>    );
 
     // Unsized depth stencil formats
     //                         | Internal format        |sized | D |S | X | Format            | Type                             | Component type        | Supported                                            | Renderable                                           | Filterable    |
-    AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT,      false, 16, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,                 GL_UNSIGNED_NORMALIZED, RequireES<2, 0>,                                       RequireES<2, 0>,                                       AlwaysSupported);
-    AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT,      false, 24, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, RequireES<2, 0>,                                       RequireES<2, 0>,                                       AlwaysSupported);
-    AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT,      false, 32, 0,  0, GL_DEPTH_COMPONENT, GL_FLOAT,                          GL_FLOAT,               RequireES<2, 0>,                                       RequireES<2, 0>,                                       AlwaysSupported);
+    AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT,      false, 16, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,                 GL_UNSIGNED_NORMALIZED, RequireES<1, 0>,                                       RequireES<1, 0>,                                       AlwaysSupported);
+    AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT,      false, 24, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, RequireES<1, 0>,                                       RequireES<1, 0>,                                       AlwaysSupported);
+    AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT,      false, 32, 0,  0, GL_DEPTH_COMPONENT, GL_FLOAT,                          GL_FLOAT,               RequireES<1, 0>,                                       RequireES<1, 0>,                                       AlwaysSupported);
     AddDepthStencilFormat(&map, GL_DEPTH_STENCIL,        false, 24, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8,              GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, 0, &Extensions::packedDepthStencil>, RequireESOrExt<3, 0, &Extensions::packedDepthStencil>, AlwaysSupported);
     AddDepthStencilFormat(&map, GL_DEPTH_STENCIL,        false, 32, 8, 24, GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT,               RequireESOrExt<3, 0, &Extensions::packedDepthStencil>, RequireESOrExt<3, 0, &Extensions::packedDepthStencil>, AlwaysSupported);
-    AddDepthStencilFormat(&map, GL_STENCIL,              false,  0, 8,  0, GL_STENCIL,         GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, RequireES<2, 0>,                                       RequireES<2, 0>,                                       NeverSupported);
+    AddDepthStencilFormat(&map, GL_STENCIL,              false,  0, 8,  0, GL_STENCIL,         GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, RequireES<1, 0>,                                       RequireES<1, 0>,                                       NeverSupported);
     // clang-format on
 
     return map;
 }
 
 static const InternalFormatInfoMap &GetInternalFormatMap()
 {
     static const InternalFormatInfoMap formatMap = BuildInternalFormatInfoMap();
@@ -1064,58 +1064,67 @@ const InternalFormat &GetInternalFormatI
     if (typeIter == internalFormatIter->second.end())
     {
         return defaultInternalFormat;
     }
 
     return typeIter->second;
 }
 
-ErrorOrResult<GLuint> InternalFormat::computeRowPitch(GLsizei width,
-                                                      GLint alignment,
-                                                      GLint rowLength) const
+GLuint InternalFormat::computePixelBytes(GLenum formatType) const
+{
+    const auto &typeInfo = GetTypeInfo(formatType);
+    GLuint components    = typeInfo.specialInterpretation ? 1u : componentCount;
+    return components * typeInfo.bytes;
+}
+
+ErrorOrResult<GLuint> InternalFormat::computeRowPitch(GLenum formatType,
+                                                          GLsizei width,
+                                                          GLint alignment,
+                                                          GLint rowLength) const
 {
     // Compressed images do not use pack/unpack parameters.
     if (compressed)
     {
         ASSERT(rowLength == 0);
         return computeCompressedImageSize(Extents(width, 1, 1));
     }
 
     CheckedNumeric<GLuint> checkedWidth(rowLength > 0 ? rowLength : width);
-    CheckedNumeric<GLuint> checkedRowBytes = checkedWidth * pixelBytes;
+    CheckedNumeric<GLuint> checkedRowBytes = checkedWidth * computePixelBytes(formatType);
 
     ASSERT(alignment > 0 && isPow2(alignment));
     CheckedNumeric<GLuint> checkedAlignment(alignment);
     auto aligned = rx::roundUp(checkedRowBytes, checkedAlignment);
     ANGLE_TRY_CHECKED_MATH(aligned);
     return aligned.ValueOrDie();
 }
 
 ErrorOrResult<GLuint> InternalFormat::computeDepthPitch(GLsizei height,
                                                         GLint imageHeight,
-                                                        GLuint rowPitch)
+                                                        GLuint rowPitch) const
 {
     GLuint rows =
         (imageHeight > 0 ? static_cast<GLuint>(imageHeight) : static_cast<GLuint>(height));
     CheckedNumeric<GLuint> checkedRowPitch(rowPitch);
 
     auto depthPitch = checkedRowPitch * rows;
     ANGLE_TRY_CHECKED_MATH(depthPitch);
     return depthPitch.ValueOrDie();
 }
 
-ErrorOrResult<GLuint> InternalFormat::computeDepthPitch(GLsizei width,
-                                                        GLsizei height,
-                                                        GLint alignment,
-                                                        GLint rowLength,
-                                                        GLint imageHeight) const
+ErrorOrResult<GLuint> InternalFormat::computeDepthPitch(GLenum formatType,
+                                                            GLsizei width,
+                                                            GLsizei height,
+                                                            GLint alignment,
+                                                            GLint rowLength,
+                                                            GLint imageHeight) const
 {
     GLuint rowPitch = 0;
-    ANGLE_TRY_RESULT(computeRowPitch(width, alignment, rowLength), rowPitch);
+    ANGLE_TRY_RESULT(computeRowPitch(formatType, width, alignment, rowLength), rowPitch);
     return computeDepthPitch(height, imageHeight, rowPitch);
 }
 
 ErrorOrResult<GLuint> InternalFormat::computeCompressedImageSize(const Extents &size) const
 {
     CheckedNumeric<GLuint> checkedWidth(size.width);
     CheckedNumeric<GLuint> checkedHeight(size.height);
     CheckedNumeric<GLuint> checkedDepth(size.depth);
@@ -1125,75 +1134,78 @@ ErrorOrResult<GLuint> InternalFormat::co
     ASSERT(compressed);
     auto numBlocksWide = (checkedWidth + checkedBlockWidth - 1u) / checkedBlockWidth;
     auto numBlocksHigh = (checkedHeight + checkedBlockHeight - 1u) / checkedBlockHeight;
     auto bytes         = numBlocksWide * numBlocksHigh * pixelBytes * checkedDepth;
     ANGLE_TRY_CHECKED_MATH(bytes);
     return bytes.ValueOrDie();
 }
 
-ErrorOrResult<GLuint> InternalFormat::computeSkipBytes(GLuint rowPitch,
+ErrorOrResult<GLuint> InternalFormat::computeSkipBytes(GLenum formatType,
+                                                       GLuint rowPitch,
                                                        GLuint depthPitch,
                                                        const PixelStoreStateBase &state,
                                                        bool is3D) const
 {
     CheckedNumeric<GLuint> checkedRowPitch(rowPitch);
     CheckedNumeric<GLuint> checkedDepthPitch(depthPitch);
     CheckedNumeric<GLuint> checkedSkipImages(static_cast<GLuint>(state.skipImages));
     CheckedNumeric<GLuint> checkedSkipRows(static_cast<GLuint>(state.skipRows));
     CheckedNumeric<GLuint> checkedSkipPixels(static_cast<GLuint>(state.skipPixels));
-    CheckedNumeric<GLuint> checkedPixelBytes(pixelBytes);
+    CheckedNumeric<GLuint> checkedPixelBytes(computePixelBytes(formatType));
     auto checkedSkipImagesBytes = checkedSkipImages * checkedDepthPitch;
     if (!is3D)
     {
         checkedSkipImagesBytes = 0;
     }
     auto skipBytes = checkedSkipImagesBytes + checkedSkipRows * checkedRowPitch +
                      checkedSkipPixels * checkedPixelBytes;
     ANGLE_TRY_CHECKED_MATH(skipBytes);
     return skipBytes.ValueOrDie();
 }
 
 ErrorOrResult<GLuint> InternalFormat::computePackUnpackEndByte(
+    GLenum formatType,
     const Extents &size,
     const PixelStoreStateBase &state,
     bool is3D) const
 {
     GLuint rowPitch = 0;
-    ANGLE_TRY_RESULT(computeRowPitch(size.width, state.alignment, state.rowLength),
+    ANGLE_TRY_RESULT(computeRowPitch(formatType, size.width, state.alignment, state.rowLength),
                      rowPitch);
 
     GLuint depthPitch = 0;
     if (is3D)
     {
         ANGLE_TRY_RESULT(computeDepthPitch(size.height, state.imageHeight, rowPitch), depthPitch);
     }
 
     CheckedNumeric<GLuint> checkedCopyBytes = 0;
     if (compressed)
     {
         ANGLE_TRY_RESULT(computeCompressedImageSize(size), checkedCopyBytes);
     }
     else if (size.height != 0 && (!is3D || size.depth != 0))
     {
-        CheckedNumeric<GLuint> bytes = pixelBytes;
+        CheckedNumeric<GLuint> bytes = computePixelBytes(formatType);
         checkedCopyBytes += size.width * bytes;
 
         CheckedNumeric<GLuint> heightMinusOne = size.height - 1;
         checkedCopyBytes += heightMinusOne * rowPitch;
 
         if (is3D)
         {
             CheckedNumeric<GLuint> depthMinusOne = size.depth - 1;
             checkedCopyBytes += depthMinusOne * depthPitch;
         }
     }
 
     CheckedNumeric<GLuint> checkedSkipBytes = 0;
-    ANGLE_TRY_RESULT(computeSkipBytes(rowPitch, depthPitch, state, is3D), checkedSkipBytes);
+    ANGLE_TRY_RESULT(computeSkipBytes(formatType, rowPitch, depthPitch, state, is3D),
+                     checkedSkipBytes);
 
     CheckedNumeric<GLuint> endByte = checkedCopyBytes + checkedSkipBytes;
 
     ANGLE_TRY_CHECKED_MATH(endByte);
     return endByte.ValueOrDie();
 }
 
 GLenum GetUnsizedFormat(GLenum internalFormat)
--- a/gfx/angle/checkout/src/libANGLE/formatutils.h
+++ b/gfx/angle/checkout/src/libANGLE/formatutils.h
@@ -48,38 +48,44 @@ const Type &GetTypeInfo(GLenum type);
 
 // Information about an OpenGL internal format.  Can be keyed on the internalFormat and type
 // members.
 struct InternalFormat
 {
     InternalFormat();
     InternalFormat(const InternalFormat &other);
 
-    ErrorOrResult<GLuint> computeRowPitch(GLsizei width,
+    GLuint computePixelBytes(GLenum formatType) const;
+
+    ErrorOrResult<GLuint> computeRowPitch(GLenum formatType,
+                                          GLsizei width,
                                           GLint alignment,
                                           GLint rowLength) const;
-    static ErrorOrResult<GLuint> computeDepthPitch(GLsizei height,
-                                                   GLint imageHeight,
-                                                   GLuint rowPitch);
-    ErrorOrResult<GLuint> computeDepthPitch(GLsizei width,
+    ErrorOrResult<GLuint> computeDepthPitch(GLsizei height,
+                                            GLint imageHeight,
+                                            GLuint rowPitch) const;
+    ErrorOrResult<GLuint> computeDepthPitch(GLenum formatType,
+                                            GLsizei width,
                                             GLsizei height,
                                             GLint alignment,
                                             GLint rowLength,
                                             GLint imageHeight) const;
 
     ErrorOrResult<GLuint> computeCompressedImageSize(const Extents &size) const;
 
-    ErrorOrResult<GLuint> computeSkipBytes(GLuint rowPitch,
+    ErrorOrResult<GLuint> computeSkipBytes(GLenum formatType,
+                                           GLuint rowPitch,
                                            GLuint depthPitch,
                                            const PixelStoreStateBase &state,
                                            bool is3D) const;
 
-    ErrorOrResult<GLuint> computePackUnpackEndByte(const Extents &size,
-                                                   const PixelStoreStateBase &state,
-                                                   bool is3D) const;
+    ErrorOrResult<GLuint> computePackUnpackEndByte(GLenum formatType,
+                                                       const Extents &size,
+                                                       const PixelStoreStateBase &state,
+                                                       bool is3D) const;
 
     bool isLUMA() const;
     GLenum getReadPixelsFormat() const;
     GLenum getReadPixelsType(const Version &version) const;
 
     // Return true if the format is a required renderbuffer format in the given version of the core
     // spec. Note that it isn't always clear whether all the rules that apply to core required
     // renderbuffer formats also apply to additional formats added by extensions. Because of this
@@ -155,21 +161,16 @@ struct Format
 
 const InternalFormat &GetSizedInternalFormatInfo(GLenum internalFormat);
 const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, GLenum type);
 
 // Strip sizing information from an internal format.  Doesn't necessarily validate that the internal
 // format is valid.
 GLenum GetUnsizedFormat(GLenum internalFormat);
 
-inline const InternalFormat &GetPackFormatInfo(GLenum internalFormat, GLenum type)
-{
-    return GetInternalFormatInfo(GetUnsizedFormat(internalFormat), type);
-}
-
 typedef std::set<GLenum> FormatSet;
 const FormatSet &GetAllSizedInternalFormats();
 
 // From the ESSL 3.00.4 spec:
 // Vertex shader inputs can only be float, floating-point vectors, matrices, signed and unsigned
 // integers and integer vectors. Vertex shader inputs cannot be arrays or structures.
 
 enum AttributeType
--- a/gfx/angle/checkout/src/libANGLE/params.cpp
+++ b/gfx/angle/checkout/src/libANGLE/params.cpp
@@ -13,56 +13,181 @@
 #include "libANGLE/Context.h"
 #include "libANGLE/VertexArray.h"
 
 namespace gl
 {
 
 // static
 constexpr ParamTypeInfo ParamsBase::TypeInfo;
-constexpr ParamTypeInfo HasIndexRange::TypeInfo;
+constexpr ParamTypeInfo DrawCallParams::TypeInfo;
+
+// DrawCallParams implementation.
+// Called by DrawArrays.
+DrawCallParams::DrawCallParams(GLenum mode,
+                               GLint firstVertex,
+                               GLsizei vertexCount,
+                               GLsizei instances)
+    : mMode(mode),
+      mFirstVertex(firstVertex),
+      mVertexCount(vertexCount),
+      mIndexCount(0),
+      mBaseVertex(0),
+      mType(GL_NONE),
+      mIndices(nullptr),
+      mInstances(instances),
+      mIndirect(nullptr)
+{
+}
 
-HasIndexRange::HasIndexRange()
-    : ParamsBase(nullptr), mContext(nullptr), mCount(0), mType(GL_NONE), mIndices(nullptr)
+// Called by DrawElements.
+DrawCallParams::DrawCallParams(GLenum mode,
+                               GLint indexCount,
+                               GLenum type,
+                               const void *indices,
+                               GLint baseVertex,
+                               GLsizei instances)
+    : mMode(mode),
+      mFirstVertex(0),
+      mVertexCount(0),
+      mIndexCount(indexCount),
+      mBaseVertex(baseVertex),
+      mType(type),
+      mIndices(indices),
+      mInstances(instances),
+      mIndirect(nullptr)
+{
+}
+
+// Called by DrawArraysIndirect.
+DrawCallParams::DrawCallParams(GLenum mode, const void *indirect)
+    : mMode(mode),
+      mFirstVertex(0),
+      mVertexCount(0),
+      mIndexCount(0),
+      mBaseVertex(0),
+      mType(GL_NONE),
+      mIndices(nullptr),
+      mInstances(0),
+      mIndirect(indirect)
+{
+}
+
+// Called by DrawElementsIndirect.
+DrawCallParams::DrawCallParams(GLenum mode, GLenum type, const void *indirect)
+    : mMode(mode),
+      mFirstVertex(0),
+      mVertexCount(0),
+      mIndexCount(0),
+      mBaseVertex(0),
+      mType(type),
+      mIndices(nullptr),
+      mInstances(0),
+      mIndirect(indirect)
 {
 }
 
-HasIndexRange::HasIndexRange(Context *context, GLsizei count, GLenum type, const void *indices)
-    : ParamsBase(context), mContext(context), mCount(count), mType(type), mIndices(indices)
+GLenum DrawCallParams::mode() const
+{
+    return mMode;
+}
+
+GLint DrawCallParams::firstVertex() const
 {
+    // In some cases we can know the first vertex will be fixed at zero, if we're on the "fast
+    // path". In these cases the index range is not resolved. If the first vertex is not zero,
+    // however, then it must be because the index range is resolved. This only applies to the
+    // D3D11 back-end currently.
+    ASSERT(mFirstVertex == 0 || (!isDrawElements() || mIndexRange.valid()));
+    return mFirstVertex;
+}
+
+size_t DrawCallParams::vertexCount() const
+{
+    ASSERT(!isDrawElements() || mIndexRange.valid());
+    return mVertexCount;
+}
+
+GLsizei DrawCallParams::indexCount() const
+{
+    ASSERT(isDrawElements());
+    return mIndexCount;
+}
+
+GLint DrawCallParams::baseVertex() const
+{
+    return mBaseVertex;
 }
 
-const Optional<IndexRange> &HasIndexRange::getIndexRange() const
+GLenum DrawCallParams::type() const
+{
+    ASSERT(isDrawElements());
+    return mType;
+}
+
+const void *DrawCallParams::indices() const
+{
+    return mIndices;
+}
+
+GLsizei DrawCallParams::instances() const
+{
+    return mInstances;
+}
+
+const void *DrawCallParams::indirect() const
 {
-    if (mIndexRange.valid() || !mContext)
+    return mIndirect;
+}
+
+bool DrawCallParams::isDrawElements() const
+{
+    return (mType != GL_NONE);
+}
+
+bool DrawCallParams::isDrawIndirect() const
+{
+    // This is a bit of a hack - it's quite possible for a direct call to have a zero count, but we
+    // assume these calls are filtered out before they make it to this code.
+    return (mIndexCount == 0 && mVertexCount == 0);
+}
+
+Error DrawCallParams::ensureIndexRangeResolved(const Context *context) const
+{
+    if (mIndexRange.valid() || !isDrawElements())
     {
-        return mIndexRange;
+        return NoError();
     }
 
-    const State &state = mContext->getGLState();
+    const State &state = context->getGLState();
 
     const gl::VertexArray *vao     = state.getVertexArray();
     gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
 
     if (elementArrayBuffer)
     {
         uintptr_t offset = reinterpret_cast<uintptr_t>(mIndices);
         IndexRange indexRange;
-        Error error =
-            elementArrayBuffer->getIndexRange(mContext, mType, static_cast<size_t>(offset), mCount,
-                                              state.isPrimitiveRestartEnabled(), &indexRange);
-        if (error.isError())
-        {
-            mContext->handleError(error);
-            return mIndexRange;
-        }
-
+        ANGLE_TRY(elementArrayBuffer->getIndexRange(context, mType, static_cast<size_t>(offset),
+                                                    mIndexCount, state.isPrimitiveRestartEnabled(),
+                                                    &indexRange));
         mIndexRange = indexRange;
     }
     else
     {
-        mIndexRange = ComputeIndexRange(mType, mIndices, mCount, state.isPrimitiveRestartEnabled());
+        mIndexRange =
+            ComputeIndexRange(mType, mIndices, mIndexCount, state.isPrimitiveRestartEnabled());
     }
 
-    return mIndexRange;
+    const IndexRange &indexRange = mIndexRange.value();
+    mFirstVertex                 = mBaseVertex + static_cast<GLint>(indexRange.start);
+    mVertexCount                 = indexRange.vertexCount();
+
+    return NoError();
+}
+
+const IndexRange &DrawCallParams::getIndexRange() const
+{
+    ASSERT(isDrawElements() && mIndexRange.valid());
+    return mIndexRange.value();
 }
 
 }  // namespace gl
--- a/gfx/angle/checkout/src/libANGLE/params.h
+++ b/gfx/angle/checkout/src/libANGLE/params.h
@@ -9,16 +9,17 @@
 
 #ifndef LIBANGLE_PARAMS_H_
 #define LIBANGLE_PARAMS_H_
 
 #include "angle_gl.h"
 #include "common/Optional.h"
 #include "common/angleutils.h"
 #include "common/mathutil.h"
+#include "libANGLE/Error.h"
 #include "libANGLE/entry_points_enum_autogen.h"
 
 namespace gl
 {
 class Context;
 
 template <EntryPoint EP>
 struct EntryPointParam;
@@ -63,104 +64,213 @@ class ParamsBase : angle::NonCopyable
 
 // static
 template <EntryPoint EP, typename... ArgsT>
 ANGLE_INLINE void ParamsBase::Factory(EntryPointParamType<EP> *objBuffer, ArgsT... args)
 {
     new (objBuffer) EntryPointParamType<EP>(args...);
 }
 
-class HasIndexRange : public ParamsBase
+// Helper class that encompasses draw call parameters. It uses the HasIndexRange
+// helper class to only pull index range info lazily to prevent unnecessary readback.
+// It is also used when syncing state for the VertexArray implementation, since the
+// vertex and index buffer updates depend on draw call parameters.
+class DrawCallParams final : angle::NonCopyable
 {
   public:
-    // Dummy placeholder that can't generate an index range.
-    HasIndexRange();
-    HasIndexRange(Context *context, GLsizei count, GLenum type, const void *indices);
+    // Called by DrawArrays.
+    DrawCallParams(GLenum mode, GLint firstVertex, GLsizei vertexCount, GLsizei instances);
+
+    // Called by DrawElements.
+    DrawCallParams(GLenum mode,
+                   GLint indexCount,
+                   GLenum type,
+                   const void *indices,
+                   GLint baseVertex,
+                   GLsizei instances);
+
+    // Called by DrawArraysIndirect.
+    DrawCallParams(GLenum mode, const void *indirect);
+
+    // Called by DrawElementsIndirect.
+    DrawCallParams(GLenum mode, GLenum type, const void *indirect);
+
+    GLenum mode() const;
+
+    // This value is the sum of 'baseVertex' and the first indexed vertex for DrawElements calls.
+    GLint firstVertex() const;
+
+    size_t vertexCount() const;
+    GLsizei indexCount() const;
+    GLint baseVertex() const;
+    GLenum type() const;
+    const void *indices() const;
+    GLsizei instances() const;
+    const void *indirect() const;
+
+    Error ensureIndexRangeResolved(const Context *context) const;
+    bool isDrawElements() const;
+    bool isDrawIndirect() const;
+
+    // ensureIndexRangeResolved must be called first.
+    const IndexRange &getIndexRange() const;
+
+    template <typename T>
+    T getClampedVertexCount() const;
 
     template <EntryPoint EP, typename... ArgsT>
-    static void Factory(HasIndexRange *objBuffer, ArgsT... args);
+    static void Factory(DrawCallParams *objBuffer, ArgsT... args);
 
-    const Optional<IndexRange> &getIndexRange() const;
-
-    ANGLE_PARAM_TYPE_INFO(HasIndexRange, ParamsBase);
+    ANGLE_PARAM_TYPE_INFO(DrawCallParams, ParamsBase);
 
   private:
-    Context *mContext;
-    GLsizei mCount;
+    GLenum mMode;
+    mutable Optional<IndexRange> mIndexRange;
+    mutable GLint mFirstVertex;
+    mutable size_t mVertexCount;
+    GLint mIndexCount;
+    GLint mBaseVertex;
     GLenum mType;
-    const GLvoid *mIndices;
-    mutable Optional<IndexRange> mIndexRange;
+    const void *mIndices;
+    GLsizei mInstances;
+    const void *mIndirect;
 };
 
+template <typename T>
+T DrawCallParams::getClampedVertexCount() const
+{
+    constexpr size_t kMax = static_cast<size_t>(std::numeric_limits<T>::max());
+    return static_cast<T>(mVertexCount > kMax ? kMax : mVertexCount);
+}
+
 // Entry point funcs essentially re-map different entry point parameter arrays into
 // the format the parameter type class expects. For example, for HasIndexRange, for the
 // various indexed draw calls, they drop parameters that aren't useful and re-arrange
 // the rest.
 #define ANGLE_ENTRY_POINT_FUNC(NAME, CLASS, ...)    \
     \
 template<> struct EntryPointParam<EntryPoint::NAME> \
     {                                               \
         using Type = CLASS;                         \
     };                                              \
     \
 template<> inline void CLASS::Factory<EntryPoint::NAME>(__VA_ARGS__)
 
+ANGLE_ENTRY_POINT_FUNC(DrawArrays,
+                       DrawCallParams,
+                       DrawCallParams *objBuffer,
+                       Context *context,
+                       GLenum mode,
+                       GLint first,
+                       GLsizei count)
+{
+    return ParamsBase::Factory<EntryPoint::DrawArrays>(objBuffer, mode, first, count, 0);
+}
+
+ANGLE_ENTRY_POINT_FUNC(DrawArraysInstanced,
+                       DrawCallParams,
+                       DrawCallParams *objBuffer,
+                       Context *context,
+                       GLenum mode,
+                       GLint first,
+                       GLsizei count,
+                       GLsizei instanceCount)
+{
+    return ParamsBase::Factory<EntryPoint::DrawArraysInstanced>(objBuffer, mode, first, count,
+                                                                instanceCount);
+}
+
+ANGLE_ENTRY_POINT_FUNC(DrawArraysInstancedANGLE,
+                       DrawCallParams,
+                       DrawCallParams *objBuffer,
+                       Context *context,
+                       GLenum mode,
+                       GLint first,
+                       GLsizei count,
+                       GLsizei instanceCount)
+{
+    return ParamsBase::Factory<EntryPoint::DrawArraysInstancedANGLE>(objBuffer, mode, first, count,
+                                                                     instanceCount);
+}
+
+ANGLE_ENTRY_POINT_FUNC(DrawArraysIndirect,
+                       DrawCallParams,
+                       DrawCallParams *objBuffer,
+                       Context *context,
+                       GLenum mode,
+                       const void *indirect)
+{
+    return ParamsBase::Factory<EntryPoint::DrawArraysIndirect>(objBuffer, mode, indirect);
+}
+
+ANGLE_ENTRY_POINT_FUNC(DrawElementsIndirect,
+                       DrawCallParams,
+                       DrawCallParams *objBuffer,
+                       Context *context,
+                       GLenum mode,
+                       GLenum type,
+                       const void *indirect)
+{
+    return ParamsBase::Factory<EntryPoint::DrawElementsIndirect>(objBuffer, mode, type, indirect);
+}
+
 ANGLE_ENTRY_POINT_FUNC(DrawElements,
-                       HasIndexRange,
-                       HasIndexRange *objBuffer,
+                       DrawCallParams,
+                       DrawCallParams *objBuffer,
                        Context *context,
-                       GLenum /*mode*/,
+                       GLenum mode,
                        GLsizei count,
                        GLenum type,
                        const void *indices)
 {
-    return ParamsBase::Factory<EntryPoint::DrawElements>(objBuffer, context, count, type, indices);
+    return ParamsBase::Factory<EntryPoint::DrawElements>(objBuffer, mode, count, type, indices, 0,
+                                                         0);
 }
 
 ANGLE_ENTRY_POINT_FUNC(DrawElementsInstanced,
-                       HasIndexRange,
-                       HasIndexRange *objBuffer,
+                       DrawCallParams,
+                       DrawCallParams *objBuffer,
                        Context *context,
-                       GLenum /*mode*/,
+                       GLenum mode,
                        GLsizei count,
                        GLenum type,
                        const void *indices,
-                       GLsizei /*instanceCount*/)
+                       GLsizei instanceCount)
 {
-    return ParamsBase::Factory<EntryPoint::DrawElementsInstanced>(objBuffer, context, count, type,
-                                                                  indices);
+    return ParamsBase::Factory<EntryPoint::DrawElementsInstanced>(objBuffer, mode, count, type,
+                                                                  indices, 0, instanceCount);
 }
 
 ANGLE_ENTRY_POINT_FUNC(DrawElementsInstancedANGLE,
-                       HasIndexRange,
-                       HasIndexRange *objBuffer,
+                       DrawCallParams,
+                       DrawCallParams *objBuffer,
                        Context *context,
-                       GLenum /*mode*/,
+                       GLenum mode,
                        GLsizei count,
                        GLenum type,
                        const void *indices,
-                       GLsizei /*instanceCount*/)
+                       GLsizei instanceCount)
 {
-    return ParamsBase::Factory<EntryPoint::DrawElementsInstancedANGLE>(objBuffer, context, count,
-                                                                       type, indices);
+    return ParamsBase::Factory<EntryPoint::DrawElementsInstancedANGLE>(objBuffer, mode, count, type,
+                                                                       indices, 0, instanceCount);
 }
 
 ANGLE_ENTRY_POINT_FUNC(DrawRangeElements,
-                       HasIndexRange,
-                       HasIndexRange *objBuffer,
+                       DrawCallParams,
+                       DrawCallParams *objBuffer,
                        Context *context,
-                       GLenum /*mode*/,
+                       GLenum mode,
                        GLuint /*start*/,
                        GLuint /*end*/,
                        GLsizei count,
                        GLenum type,
                        const void *indices)
 {
-    return ParamsBase::Factory<EntryPoint::DrawRangeElements>(objBuffer, context, count, type,
-                                                              indices);
+    return ParamsBase::Factory<EntryPoint::DrawRangeElements>(objBuffer, mode, count, type, indices,
+                                                              0, 0);
 }
 
 #undef ANGLE_ENTRY_POINT_FUNC
 
 template <EntryPoint EP>
 struct EntryPointParam
 {
     using Type = ParamsBase;
--- a/gfx/angle/checkout/src/libANGLE/queryconversions.cpp
+++ b/gfx/angle/checkout/src/libANGLE/queryconversions.cpp
@@ -5,18 +5,18 @@
 //
 
 // queryconversions.cpp: Implementation of state query cast conversions
 
 #include "libANGLE/queryconversions.h"
 
 #include <vector>
 
+#include "common/utilities.h"
 #include "libANGLE/Context.h"
-#include "common/utilities.h"
 
 namespace gl
 {
 
 namespace
 {
 
 GLint64 ExpandFloatToInteger(GLfloat value)
@@ -26,24 +26,32 @@ GLint64 ExpandFloatToInteger(GLfloat val
 
 template <typename QueryT, typename NativeT>
 QueryT CastFromStateValueToInt(GLenum pname, NativeT value)
 {
     GLenum nativeType = GLTypeToGLenum<NativeT>::value;
 
     if (nativeType == GL_FLOAT)
     {
-        // RGBA color values and DepthRangeF values are converted to integer using Equation 2.4 from Table 4.5
-        if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
+        // RGBA color values and DepthRangeF values are converted to integer using Equation 2.4 from
+        // Table 4.5
+        switch (pname)
         {
-            return clampCast<QueryT>(ExpandFloatToInteger(static_cast<GLfloat>(value)));
-        }
-        else
-        {
-            return clampCast<QueryT>(std::round(value));
+            case GL_DEPTH_RANGE:
+            case GL_COLOR_CLEAR_VALUE:
+            case GL_DEPTH_CLEAR_VALUE:
+            case GL_BLEND_COLOR:
+            // GLES1 emulation:
+            // Also, several GLES1.x values need to be converted to integer with
+            // ExpandFloatToInteger rather than rounding. See GLES 1.1 spec 6.1.2 "Data
+            // Conversions".
+            case GL_ALPHA_TEST_REF:
+                return clampCast<QueryT>(ExpandFloatToInteger(static_cast<GLfloat>(value)));
+            default:
+                return clampCast<QueryT>(std::round(value));
         }
     }
 
     return clampCast<QueryT>(value);
 }
 
 template <typename NativeT, typename QueryT>
 NativeT CastQueryValueToInt(GLenum pname, QueryT value)
@@ -146,18 +154,21 @@ template GLint CastQueryValueTo<GLint, G
 template GLboolean CastQueryValueTo<GLboolean, GLint>(GLenum pname, GLint value);
 template GLint CastQueryValueTo<GLint, GLint>(GLenum pname, GLint value);
 template GLfloat CastQueryValueTo<GLfloat, GLint>(GLenum pname, GLint value);
 template GLfloat CastQueryValueTo<GLfloat, GLfloat>(GLenum pname, GLfloat value);
 template GLuint CastQueryValueTo<GLuint, GLint>(GLenum pname, GLint value);
 template GLuint CastQueryValueTo<GLuint, GLfloat>(GLenum pname, GLfloat value);
 
 template <typename QueryT>
-void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
-                     unsigned int numParams, QueryT *outParams)
+void CastStateValues(Context *context,
+                     GLenum nativeType,
+                     GLenum pname,
+                     unsigned int numParams,
+                     QueryT *outParams)
 {
     if (nativeType == GL_INT)
     {
         std::vector<GLint> intParams(numParams, 0);
         context->getIntegervImpl(pname, intParams.data());
 
         for (unsigned int i = 0; i < numParams; ++i)
         {
@@ -166,17 +177,18 @@ void CastStateValues(Context *context, G
     }
     else if (nativeType == GL_BOOL)
     {
         std::vector<GLboolean> boolParams(numParams, GL_FALSE);
         context->getBooleanvImpl(pname, boolParams.data());
 
         for (unsigned int i = 0; i < numParams; ++i)
         {
-            outParams[i] = (boolParams[i] == GL_FALSE ? static_cast<QueryT>(0) : static_cast<QueryT>(1));
+            outParams[i] =
+                (boolParams[i] == GL_FALSE ? static_cast<QueryT>(0) : static_cast<QueryT>(1));
         }
     }
     else if (nativeType == GL_FLOAT)
     {
         std::vector<GLfloat> floatParams(numParams, 0.0f);
         context->getFloatvImpl(pname, floatParams.data());
 
         for (unsigned int i = 0; i < numParams; ++i)
@@ -189,17 +201,18 @@ void CastStateValues(Context *context, G
         std::vector<GLint64> int64Params(numParams, 0);
         context->getInteger64v(pname, int64Params.data());
 
         for (unsigned int i = 0; i < numParams; ++i)
         {
             outParams[i] = CastFromStateValue<QueryT>(pname, int64Params[i]);
         }
     }
-    else UNREACHABLE();
+    else
+        UNREACHABLE();
 }
 
 // Explicit template instantiation (how we export template functions in different files)
 // The calls below will make CastStateValues successfully link with the GL state query types
 // The GL state query API types are: bool, int, uint, float, int64, uint64
 
 template void CastStateValues<GLboolean>(Context *, GLenum, GLenum, unsigned int, GLboolean *);
 template void CastStateValues<GLint>(Context *, GLenum, GLenum, unsigned int, GLint *);
--- a/gfx/angle/checkout/src/libANGLE/queryutils.cpp
+++ b/gfx/angle/checkout/src/libANGLE/queryutils.cpp
@@ -28,17 +28,17 @@
 namespace gl
 {
 
 namespace
 {
 
 template <typename ParamType>
 void QueryTexLevelParameterBase(const Texture *texture,
-                                GLenum target,
+                                TextureTarget target,
                                 GLint level,
                                 GLenum pname,
                                 ParamType *params)
 {
     ASSERT(texture != nullptr);
     const InternalFormat *info = texture->getTextureState().getImageDesc(target, level).format.info;
 
     switch (pname)
@@ -722,23 +722,23 @@ void GetShaderVariableBufferResourceProp
             for (size_t memberIndex = 0;
                  memberIndex < buffer.memberIndexes.size() && *outputPosition < bufSize;
                  ++memberIndex)
             {
                 params[(*outputPosition)++] = clampCast<GLint>(buffer.memberIndexes[memberIndex]);
             }
             break;
         case GL_REFERENCED_BY_VERTEX_SHADER:
-            params[(*outputPosition)++] = static_cast<GLint>(buffer.vertexStaticUse);
+            params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Vertex));
             break;
         case GL_REFERENCED_BY_FRAGMENT_SHADER:
-            params[(*outputPosition)++] = static_cast<GLint>(buffer.fragmentStaticUse);
+            params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Fragment));
             break;
         case GL_REFERENCED_BY_COMPUTE_SHADER:
-            params[(*outputPosition)++] = static_cast<GLint>(buffer.computeStaticUse);
+            params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Compute));
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
 void GetInterfaceBlockResourceProperty(const InterfaceBlock &block,
@@ -843,18 +843,29 @@ void QueryFramebufferAttachmentParameter
             *params = attachmentObject->id();
             break;
 
         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
             *params = attachmentObject->mipLevel();
             break;
 
         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
-            *params = attachmentObject->cubeMapFace();
-            break;
+        {
+            TextureTarget face = attachmentObject->cubeMapFace();
+            if (face != TextureTarget::InvalidEnum)
+            {
+                *params = ToGLenum(attachmentObject->cubeMapFace());
+            }
+            else
+            {
+                // This happens when the attachment isn't a texture cube map face
+                *params = GL_NONE;
+            }
+        }
+        break;
 
         case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
             *params = attachmentObject->getRedSize();
             break;
 
         case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
             *params = attachmentObject->getGreenSize();
             break;
@@ -1003,16 +1014,28 @@ void QueryProgramiv(const Context *conte
             params[0]                          = localSize[0];
             params[1]                          = localSize[1];
             params[2]                          = localSize[2];
         }
         break;
         case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
             *params = program->getActiveAtomicCounterBufferCount();
             break;
+        case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
+            *params = program->getGeometryShaderInputPrimitiveType();
+            break;
+        case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
+            *params = program->getGeometryShaderOutputPrimitiveType();
+            break;
+        case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
+            *params = program->getGeometryShaderMaxVertices();
+            break;
+        case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
+            *params = program->getGeometryShaderInvocations();
+            break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
 void QueryRenderbufferiv(const Context *context,
                          const Renderbuffer *renderbuffer,
@@ -1070,17 +1093,17 @@ void QueryRenderbufferiv(const Context *
 
 void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params)
 {
     ASSERT(shader != nullptr);
 
     switch (pname)
     {
         case GL_SHADER_TYPE:
-            *params = shader->getType();
+            *params = static_cast<GLint>(ToGLenum(shader->getType()));
             return;
         case GL_DELETE_STATUS:
             *params = shader->isFlaggedForDeletion();
             return;
         case GL_COMPILE_STATUS:
             *params = shader->isCompiled(context) ? GL_TRUE : GL_FALSE;
             return;
         case GL_INFO_LOG_LENGTH:
@@ -1094,26 +1117,26 @@ void QueryShaderiv(const Context *contex
             return;
         default:
             UNREACHABLE();
             break;
     }
 }
 
 void QueryTexLevelParameterfv(const Texture *texture,
-                              GLenum target,
+                              TextureTarget target,
                               GLint level,
                               GLenum pname,
                               GLfloat *params)
 {
     QueryTexLevelParameterBase(texture, target, level, pname, params);
 }
 
 void QueryTexLevelParameteriv(const Texture *texture,
-                              GLenum target,
+                              TextureTarget target,
                               GLint level,
                               GLenum pname,
                               GLint *params)
 {
     QueryTexLevelParameterBase(texture, target, level, pname, params);
 }
 
 void QueryTexParameterfv(const Texture *texture, GLenum pname, GLfloat *params)
@@ -1397,23 +1420,23 @@ GLint GetUniformResourceProperty(const P
 
         case GL_MATRIX_STRIDE:
             return uniform.blockInfo.matrixStride;
 
         case GL_IS_ROW_MAJOR:
             return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
 
         case GL_REFERENCED_BY_VERTEX_SHADER:
-            return uniform.vertexStaticUse;
+            return uniform.isActive(ShaderType::Vertex);
 
         case GL_REFERENCED_BY_FRAGMENT_SHADER:
-            return uniform.fragmentStaticUse;
+            return uniform.isActive(ShaderType::Fragment);
 
         case GL_REFERENCED_BY_COMPUTE_SHADER:
-            return uniform.computeStaticUse;
+            return uniform.isActive(ShaderType::Compute);
 
         case GL_ATOMIC_COUNTER_BUFFER_INDEX:
             return (uniform.isAtomicCounter() ? uniform.bufferIndex : -1);
 
         default:
             UNREACHABLE();
             return 0;
     }
@@ -1440,23 +1463,23 @@ GLint GetBufferVariableResourceProperty(
 
         case GL_MATRIX_STRIDE:
             return bufferVariable.blockInfo.matrixStride;
 
         case GL_IS_ROW_MAJOR:
             return static_cast<GLint>(bufferVariable.blockInfo.isRowMajorMatrix);
 
         case GL_REFERENCED_BY_VERTEX_SHADER:
-            return bufferVariable.vertexStaticUse;
+            return bufferVariable.isActive(ShaderType::Vertex);
 
         case GL_REFERENCED_BY_FRAGMENT_SHADER:
-            return bufferVariable.fragmentStaticUse;
+            return bufferVariable.isActive(ShaderType::Fragment);
 
         case GL_REFERENCED_BY_COMPUTE_SHADER:
-            return bufferVariable.computeStaticUse;
+            return bufferVariable.isActive(ShaderType::Compute);
 
         case GL_TOP_LEVEL_ARRAY_SIZE:
             return bufferVariable.topLevelArraySize;
 
         case GL_TOP_LEVEL_ARRAY_STRIDE:
             return bufferVariable.blockInfo.topLevelArrayStride;
 
         default:
--- a/gfx/angle/checkout/src/libANGLE/queryutils.h
+++ b/gfx/angle/checkout/src/libANGLE/queryutils.h
@@ -6,16 +6,17 @@
 
 // queryutils.h: Utilities for querying values from GL objects
 
 #ifndef LIBANGLE_QUERYUTILS_H_
 #define LIBANGLE_QUERYUTILS_H_
 
 #include "angle_gl.h"
 #include "common/angleutils.h"
+#include "libANGLE/PackedGLEnums.h"
 
 #include <EGL/egl.h>
 
 namespace gl
 {
 class Buffer;
 class Context;
 class Error;
@@ -42,22 +43,22 @@ void QueryBufferParameteri64v(const Buff
 void QueryBufferPointerv(const Buffer *buffer, GLenum pname, void **params);
 void QueryProgramiv(const Context *context, const Program *program, GLenum pname, GLint *params);
 void QueryRenderbufferiv(const Context *context,
                          const Renderbuffer *renderbuffer,
                          GLenum pname,
                          GLint *params);
 void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params);
 void QueryTexLevelParameterfv(const Texture *texture,
-                              GLenum target,
+                              TextureTarget target,
                               GLint level,
                               GLenum pname,
                               GLfloat *params);
 void QueryTexLevelParameteriv(const Texture *texture,
-                              GLenum target,
+                              TextureTarget target,
                               GLint level,
                               GLenum pname,
                               GLint *params);
 void QueryTexParameterfv(const Texture *texture, GLenum pname, GLfloat *params);
 void QueryTexParameteriv(const Texture *texture, GLenum pname, GLint *params);
 void QuerySamplerParameterfv(const Sampler *sampler, GLenum pname, GLfloat *params);
 void QuerySamplerParameteriv(const Sampler *sampler, GLenum pname, GLint *params);
 
--- a/gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.h
@@ -7,29 +7,33 @@
 // BufferImpl.h: Defines the abstract rx::BufferImpl class.
 
 #ifndef LIBANGLE_RENDERER_BUFFERIMPL_H_
 #define LIBANGLE_RENDERER_BUFFERIMPL_H_
 
 #include "common/angleutils.h"
 #include "common/mathutil.h"
 #include "libANGLE/Error.h"
+#include "libANGLE/Observer.h"
 #include "libANGLE/PackedGLEnums.h"
 
 #include <stdint.h>
 
 namespace gl
 {
 class BufferState;
 class Context;
 }
 
 namespace rx
 {
-class BufferImpl : angle::NonCopyable
+// We use two set of Subject messages. The CONTENTS_CHANGED message is signaled whenever data
+// changes, to trigger re-translation or other events. Some buffers only need to be updated when the
+// underlying driver object changes - this is notified via the STORAGE_CHANGED message.
+class BufferImpl : public angle::Subject
 {
   public:
     BufferImpl(const gl::BufferState &state) : mState(state) {}
     virtual ~BufferImpl() {}
     virtual void destroy(const gl::Context *context) {}
 
     virtual gl::Error setData(const gl::Context *context,
                               gl::BufferBinding target,
--- a/gfx/angle/checkout/src/libANGLE/renderer/Format.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/Format.h
@@ -29,21 +29,25 @@ struct Format final : private angle::Non
                      rx::ColorReadFunction colorRead,
                      rx::ColorWriteFunction colorWrite,
                      GLenum componentType,
                      GLuint redBits,
                      GLuint greenBits,
                      GLuint blueBits,
                      GLuint alphaBits,
                      GLuint depthBits,
-                     GLuint stencilBits);
+                     GLuint stencilBits,
+                     GLuint pixelBytes,
+                     bool isBlock);
 
     static const Format &Get(ID id);
     static ID InternalFormatToID(GLenum internalFormat);
 
+    constexpr bool hasDepthOrStencilBits() const;
+
     ID id;
 
     // The closest matching GL internal format for the storage this format uses. Note that this
     // may be a different internal format than the one this ANGLE format is used for.
     GLenum glInternalFormat;
 
     // The format we should report to the GL layer when querying implementation formats from a FBO.
     // This might not be the same as the glInternalFormat, since some DXGI formats don't have
@@ -60,46 +64,58 @@ struct Format final : private angle::Non
     GLenum componentType;
 
     GLuint redBits;
     GLuint greenBits;
     GLuint blueBits;
     GLuint alphaBits;
     GLuint depthBits;
     GLuint stencilBits;
+
+    GLuint pixelBytes;
+
+    bool isBlock;
 };
 
 constexpr Format::Format(ID id,
                          GLenum glFormat,
                          GLenum fboFormat,
                          rx::MipGenerationFunction mipGen,
                          const rx::FastCopyFunctionMap &fastCopyFunctions,
                          rx::ColorReadFunction colorRead,
                          rx::ColorWriteFunction colorWrite,
                          GLenum componentType,
                          GLuint redBits,
                          GLuint greenBits,
                          GLuint blueBits,
                          GLuint alphaBits,
                          GLuint depthBits,
-                         GLuint stencilBits)
+                         GLuint stencilBits,
+                         GLuint pixelBytes,
+                         bool isBlock)
     : id(id),
       glInternalFormat(glFormat),
       fboImplementationInternalFormat(fboFormat),
       mipGenerationFunction(mipGen),
       colorReadFunction(colorRead),
       colorWriteFunction(colorWrite),
       fastCopyFunctions(fastCopyFunctions),
       componentType(componentType),
       redBits(redBits),
       greenBits(greenBits),
       blueBits(blueBits),
       alphaBits(alphaBits),
       depthBits(depthBits),
-      stencilBits(stencilBits)
+      stencilBits(stencilBits),
+      pixelBytes(pixelBytes),
+      isBlock(isBlock)
 {
 }
 
+constexpr bool Format::hasDepthOrStencilBits() const
+{
+    return depthBits > 0 || stencilBits > 0;
+}
 }  // namespace angle
 
 #include "libANGLE/renderer/Format_ID_autogen.inl"
 
 #endif  // LIBANGLE_RENDERER_FORMAT_H_
--- a/gfx/angle/checkout/src/libANGLE/renderer/Format_ID_autogen.inl
+++ b/gfx/angle/checkout/src/libANGLE/renderer/Format_ID_autogen.inl
@@ -9,16 +9,17 @@
 
 namespace angle
 {
 
 enum class Format::ID
 {
     NONE,
     A16_FLOAT,
+    A1R5G5B5_UNORM,
     A32_FLOAT,
     A8_UNORM,
     ASTC_10x10_SRGB_BLOCK,
     ASTC_10x10_UNORM_BLOCK,
     ASTC_10x5_SRGB_BLOCK,
     ASTC_10x5_UNORM_BLOCK,
     ASTC_10x6_SRGB_BLOCK,
     ASTC_10x6_UNORM_BLOCK,
@@ -141,11 +142,11 @@ enum class Format::ID
     R8_SINT,
     R8_SNORM,
     R8_UINT,
     R8_UNORM,
     R9G9B9E5_SHAREDEXP,
     S8_UINT
 };
 
-constexpr uint32_t kNumANGLEFormats = 132;
+constexpr uint32_t kNumANGLEFormats = 133;
 
 }  // namespace angle
--- a/gfx/angle/checkout/src/libANGLE/renderer/Format_table_autogen.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/Format_table_autogen.cpp
@@ -19,424 +19,427 @@ namespace angle
 
 static constexpr rx::FastCopyFunctionMap::Entry BGRAEntry = {GL_RGBA, GL_UNSIGNED_BYTE,
                                                              CopyBGRA8ToRGBA8};
 static constexpr rx::FastCopyFunctionMap BGRACopyFunctions = {&BGRAEntry, 1};
 static constexpr rx::FastCopyFunctionMap NoCopyFunctions;
 
 constexpr Format g_formatInfoTable[] = {
     // clang-format off
-    { Format::ID::NONE, GL_NONE, GL_NONE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_NONE, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::A16_FLOAT, GL_ALPHA16F_EXT, GL_ALPHA16F_EXT, GenerateMip<A16F>, NoCopyFunctions, ReadColor<A16F, GLfloat>, WriteColor<A16F, GLfloat>, GL_FLOAT, 0, 0, 0, 16, 0, 0 },
-    { Format::ID::A32_FLOAT, GL_ALPHA32F_EXT, GL_ALPHA32F_EXT, GenerateMip<A32F>, NoCopyFunctions, ReadColor<A32F, GLfloat>, WriteColor<A32F, GLfloat>, GL_FLOAT, 0, 0, 0, 32, 0, 0 },
-    { Format::ID::A8_UNORM, GL_ALPHA8_EXT, GL_ALPHA8_EXT, GenerateMip<A8>, NoCopyFunctions, ReadColor<A8, GLfloat>, WriteColor<A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 8, 0, 0 },
-    { Format::ID::ASTC_10x10_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_10x10_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_10x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_10x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_COMPRESSED_RGBA_ASTC_10x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_10x6_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_10x6_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_10x8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_10x8_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_COMPRESSED_RGBA_ASTC_10x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_12x10_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_12x10_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_COMPRESSED_RGBA_ASTC_12x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_12x12_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_12x12_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_4x4_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_4x4_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_5x4_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_5x4_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_5x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_5x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_6x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_6x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_6x6_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_6x6_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_8x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_8x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_8x6_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_8x6_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_COMPRESSED_RGBA_ASTC_8x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_8x8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::ASTC_8x8_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::B4G4R4A4_UNORM, GL_BGRA4_ANGLEX, GL_RGBA4, GenerateMip<A4R4G4B4>, NoCopyFunctions, ReadColor<A4R4G4B4, GLfloat>, WriteColor<A4R4G4B4, GLfloat>, GL_UNSIGNED_NORMALIZED, 4, 4, 4, 4, 0, 0 },
-    { Format::ID::B5G5R5A1_UNORM, GL_BGR5_A1_ANGLEX, GL_RGB5_A1, GenerateMip<A1R5G5B5>, NoCopyFunctions, ReadColor<A1R5G5B5, GLfloat>, WriteColor<A1R5G5B5, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 5, 5, 1, 0, 0 },
-    { Format::ID::B5G6R5_UNORM, GL_BGR565_ANGLEX, GL_RGB565, GenerateMip<B5G6R5>, NoCopyFunctions, ReadColor<B5G6R5, GLfloat>, WriteColor<B5G6R5, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 6, 5, 0, 0, 0 },
-    { Format::ID::B8G8R8A8_TYPELESS, GL_BGRA8_EXT, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, NoCopyFunctions, ReadColor<B8G8R8A8, GLfloat>, WriteColor<B8G8R8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 },
-    { Format::ID::B8G8R8A8_TYPELESS_SRGB, GL_BGRA8_SRGB_ANGLEX, GL_BGRA8_SRGB_ANGLEX, GenerateMip<B8G8R8A8>, NoCopyFunctions, ReadColor<B8G8R8A8, GLfloat>, WriteColor<B8G8R8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 },
-    { Format::ID::B8G8R8A8_UNORM, GL_BGRA8_EXT, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, BGRACopyFunctions, ReadColor<B8G8R8A8, GLfloat>, WriteColor<B8G8R8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 },
-    { Format::ID::B8G8R8A8_UNORM_SRGB, GL_BGRA8_SRGB_ANGLEX, GL_BGRA8_SRGB_ANGLEX, GenerateMip<B8G8R8A8>, NoCopyFunctions, ReadColor<B8G8R8A8, GLfloat>, WriteColor<B8G8R8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 },
-    { Format::ID::B8G8R8X8_UNORM, GL_BGRA8_EXT, GL_BGRA8_EXT, GenerateMip<B8G8R8X8>, NoCopyFunctions, ReadColor<B8G8R8X8, GLfloat>, WriteColor<B8G8R8X8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0 },
-    { Format::ID::BC1_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::BC1_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::BC1_RGB_UNORM_BLOCK, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::BC1_RGB_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::BC2_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::BC2_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::BC3_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::BC3_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::D16_UNORM, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT16, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 16, 0 },
-    { Format::ID::D24_UNORM, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT24, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 24, 0 },
-    { Format::ID::D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 24, 8 },
-    { Format::ID::D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, nullptr, NoCopyFunctions, nullptr, nullptr, GL_FLOAT, 0, 0, 0, 0, 32, 0 },
-    { Format::ID::D32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, nullptr, NoCopyFunctions, nullptr, nullptr, GL_FLOAT, 0, 0, 0, 0, 32, 8 },
-    { Format::ID::D32_UNORM, GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT32_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 32, 0 },
-    { Format::ID::EAC_R11G11_SNORM_BLOCK, GL_COMPRESSED_SIGNED_RG11_EAC, GL_COMPRESSED_SIGNED_RG11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 11, 11, 0, 0, 0, 0 },
-    { Format::ID::EAC_R11G11_UNORM_BLOCK, GL_COMPRESSED_RG11_EAC, GL_COMPRESSED_RG11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 11, 11, 0, 0, 0, 0 },
-    { Format::ID::EAC_R11_SNORM_BLOCK, GL_COMPRESSED_SIGNED_R11_EAC, GL_COMPRESSED_SIGNED_R11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 11, 0, 0, 0, 0, 0 },
-    { Format::ID::EAC_R11_UNORM_BLOCK, GL_COMPRESSED_R11_EAC, GL_COMPRESSED_R11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 11, 0, 0, 0, 0, 0 },
-    { Format::ID::ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0 },
-    { Format::ID::ETC1_R8G8B8_UNORM_BLOCK, GL_ETC1_RGB8_OES, GL_ETC1_RGB8_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0 },
-    { Format::ID::ETC2_R8G8B8A1_SRGB_BLOCK, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 1, 0, 0 },
-    { Format::ID::ETC2_R8G8B8A1_UNORM_BLOCK, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 1, 0, 0 },
-    { Format::ID::ETC2_R8G8B8A8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 },
-    { Format::ID::ETC2_R8G8B8A8_UNORM_BLOCK, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_RGBA8_ETC2_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 },
-    { Format::ID::ETC2_R8G8B8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ETC2, GL_COMPRESSED_SRGB8_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0 },
-    { Format::ID::ETC2_R8G8B8_UNORM_BLOCK, GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_RGB8_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0 },
-    { Format::ID::L16A16_FLOAT, GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA16F_EXT, GenerateMip<L16A16F>, NoCopyFunctions, ReadColor<L16A16F, GLfloat>, WriteColor<L16A16F, GLfloat>, GL_FLOAT, 0, 0, 0, 16, 0, 0 },
-    { Format::ID::L16_FLOAT, GL_LUMINANCE16F_EXT, GL_LUMINANCE16F_EXT, GenerateMip<L16F>, NoCopyFunctions, ReadColor<L16F, GLfloat>, WriteColor<L16F, GLfloat>, GL_FLOAT, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::L32A32_FLOAT, GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA32F_EXT, GenerateMip<L32A32F>, NoCopyFunctions, ReadColor<L32A32F, GLfloat>, WriteColor<L32A32F, GLfloat>, GL_FLOAT, 0, 0, 0, 32, 0, 0 },
-    { Format::ID::L32_FLOAT, GL_LUMINANCE32F_EXT, GL_LUMINANCE32F_EXT, GenerateMip<L32F>, NoCopyFunctions, ReadColor<L32F, GLfloat>, WriteColor<L32F, GLfloat>, GL_FLOAT, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::L8A8_UNORM, GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip<L8A8>, NoCopyFunctions, ReadColor<L8A8, GLfloat>, WriteColor<L8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 8, 0, 0 },
-    { Format::ID::L8_UNORM, GL_LUMINANCE8_EXT, GL_LUMINANCE8_EXT, GenerateMip<L8>, NoCopyFunctions, ReadColor<L8, GLfloat>, WriteColor<L8, GLfloat>, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 },
-    { Format::ID::R10G10B10A2_UINT, GL_RGB10_A2UI, GL_RGB10_A2UI, GenerateMip<R10G10B10A2>, NoCopyFunctions, ReadColor<R10G10B10A2, GLuint>, WriteColor<R10G10B10A2, GLuint>, GL_UNSIGNED_INT, 10, 10, 10, 2, 0, 0 },
-    { Format::ID::R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, GenerateMip<R10G10B10A2>, NoCopyFunctions, ReadColor<R10G10B10A2, GLfloat>, WriteColor<R10G10B10A2, GLfloat>, GL_UNSIGNED_NORMALIZED, 10, 10, 10, 2, 0, 0 },
-    { Format::ID::R11G11B10_FLOAT, GL_R11F_G11F_B10F, GL_R11F_G11F_B10F, GenerateMip<R11G11B10F>, NoCopyFunctions, ReadColor<R11G11B10F, GLfloat>, WriteColor<R11G11B10F, GLfloat>, GL_FLOAT, 11, 11, 10, 0, 0, 0 },
-    { Format::ID::R16G16B16A16_FLOAT, GL_RGBA16F, GL_RGBA16F, GenerateMip<R16G16B16A16F>, NoCopyFunctions, ReadColor<R16G16B16A16F, GLfloat>, WriteColor<R16G16B16A16F, GLfloat>, GL_FLOAT, 16, 16, 16, 16, 0, 0 },
-    { Format::ID::R16G16B16A16_SINT, GL_RGBA16I, GL_RGBA16I, GenerateMip<R16G16B16A16S>, NoCopyFunctions, ReadColor<R16G16B16A16S, GLint>, WriteColor<R16G16B16A16S, GLint>, GL_INT, 16, 16, 16, 16, 0, 0 },
-    { Format::ID::R16G16B16A16_SNORM, GL_RGBA16_SNORM_EXT, GL_RGBA16_SNORM_EXT, GenerateMip<R16G16B16A16S>, NoCopyFunctions, ReadColor<R16G16B16A16S, GLfloat>, WriteColor<R16G16B16A16S, GLfloat>, GL_SIGNED_NORMALIZED, 16, 16, 16, 16, 0, 0 },
-    { Format::ID::R16G16B16A16_UINT, GL_RGBA16UI, GL_RGBA16UI, GenerateMip<R16G16B16A16>, NoCopyFunctions, ReadColor<R16G16B16A16, GLuint>, WriteColor<R16G16B16A16, GLuint>, GL_UNSIGNED_INT, 16, 16, 16, 16, 0, 0 },
-    { Format::ID::R16G16B16A16_UNORM, GL_RGBA16_EXT, GL_RGBA16_EXT, GenerateMip<R16G16B16A16>, NoCopyFunctions, ReadColor<R16G16B16A16, GLfloat>, WriteColor<R16G16B16A16, GLfloat>, GL_UNSIGNED_NORMALIZED, 16, 16, 16, 16, 0, 0 },
-    { Format::ID::R16G16B16_FLOAT, GL_RGB16F, GL_RGB16F, GenerateMip<R16G16B16F>, NoCopyFunctions, ReadColor<R16G16B16F, GLfloat>, WriteColor<R16G16B16F, GLfloat>, GL_FLOAT, 16, 16, 16, 0, 0, 0 },
-    { Format::ID::R16G16B16_SINT, GL_RGB16I, GL_RGB16I, GenerateMip<R16G16B16S>, NoCopyFunctions, ReadColor<R16G16B16S, GLint>, WriteColor<R16G16B16S, GLint>, GL_INT, 16, 16, 16, 0, 0, 0 },
-    { Format::ID::R16G16B16_SNORM, GL_RGB16_SNORM_EXT, GL_RGB16_SNORM_EXT, GenerateMip<R16G16B16S>, NoCopyFunctions, ReadColor<R16G16B16S, GLfloat>, WriteColor<R16G16B16S, GLfloat>, GL_SIGNED_NORMALIZED, 16, 16, 16, 0, 0, 0 },
-    { Format::ID::R16G16B16_UINT, GL_RGB16UI, GL_RGB16UI, GenerateMip<R16G16B16>, NoCopyFunctions, ReadColor<R16G16B16, GLuint>, WriteColor<R16G16B16, GLuint>, GL_UNSIGNED_INT, 16, 16, 16, 0, 0, 0 },
-    { Format::ID::R16G16B16_UNORM, GL_RGB16_EXT, GL_RGB16_EXT, GenerateMip<R16G16B16>, NoCopyFunctions, ReadColor<R16G16B16, GLfloat>, WriteColor<R16G16B16, GLfloat>, GL_UNSIGNED_NORMALIZED, 16, 16, 16, 0, 0, 0 },
-    { Format::ID::R16G16_FLOAT, GL_RG16F, GL_RG16F, GenerateMip<R16G16F>, NoCopyFunctions, ReadColor<R16G16F, GLfloat>, WriteColor<R16G16F, GLfloat>, GL_FLOAT, 16, 16, 0, 0, 0, 0 },
-    { Format::ID::R16G16_SINT, GL_RG16I, GL_RG16I, GenerateMip<R16G16S>, NoCopyFunctions, ReadColor<R16G16S, GLint>, WriteColor<R16G16S, GLint>, GL_INT, 16, 16, 0, 0, 0, 0 },
-    { Format::ID::R16G16_SNORM, GL_RG16_SNORM_EXT, GL_RG16_SNORM_EXT, GenerateMip<R16G16S>, NoCopyFunctions, ReadColor<R16G16S, GLfloat>, WriteColor<R16G16S, GLfloat>, GL_SIGNED_NORMALIZED, 16, 16, 0, 0, 0, 0 },
-    { Format::ID::R16G16_UINT, GL_RG16UI, GL_RG16UI, GenerateMip<R16G16>, NoCopyFunctions, ReadColor<R16G16, GLuint>, WriteColor<R16G16, GLuint>, GL_UNSIGNED_INT, 16, 16, 0, 0, 0, 0 },
-    { Format::ID::R16G16_UNORM, GL_RG16_EXT, GL_RG16_EXT, GenerateMip<R16G16>, NoCopyFunctions, ReadColor<R16G16, GLfloat>, WriteColor<R16G16, GLfloat>, GL_UNSIGNED_NORMALIZED, 16, 16, 0, 0, 0, 0 },
-    { Format::ID::R16_FLOAT, GL_R16F, GL_R16F, GenerateMip<R16F>, NoCopyFunctions, ReadColor<R16F, GLfloat>, WriteColor<R16F, GLfloat>, GL_FLOAT, 16, 0, 0, 0, 0, 0 },
-    { Format::ID::R16_SINT, GL_R16I, GL_R16I, GenerateMip<R16S>, NoCopyFunctions, ReadColor<R16S, GLint>, WriteColor<R16S, GLint>, GL_INT, 16, 0, 0, 0, 0, 0 },
-    { Format::ID::R16_SNORM, GL_R16_SNORM_EXT, GL_R16_SNORM_EXT, GenerateMip<R16S>, NoCopyFunctions, ReadColor<R16S, GLfloat>, WriteColor<R16S, GLfloat>, GL_SIGNED_NORMALIZED, 16, 0, 0, 0, 0, 0 },
-    { Format::ID::R16_UINT, GL_R16UI, GL_R16UI, GenerateMip<R16>, NoCopyFunctions, ReadColor<R16, GLuint>, WriteColor<R16, GLuint>, GL_UNSIGNED_INT, 16, 0, 0, 0, 0, 0 },
-    { Format::ID::R16_UNORM, GL_R16_EXT, GL_R16_EXT, GenerateMip<R16>, NoCopyFunctions, ReadColor<R16, GLfloat>, WriteColor<R16, GLfloat>, GL_UNSIGNED_NORMALIZED, 16, 0, 0, 0, 0, 0 },
-    { Format::ID::R32G32B32A32_FLOAT, GL_RGBA32F, GL_RGBA32F, GenerateMip<R32G32B32A32F>, NoCopyFunctions, ReadColor<R32G32B32A32F, GLfloat>, WriteColor<R32G32B32A32F, GLfloat>, GL_FLOAT, 32, 32, 32, 32, 0, 0 },
-    { Format::ID::R32G32B32A32_SINT, GL_RGBA32I, GL_RGBA32I, GenerateMip<R32G32B32A32S>, NoCopyFunctions, ReadColor<R32G32B32A32S, GLint>, WriteColor<R32G32B32A32S, GLint>, GL_INT, 32, 32, 32, 32, 0, 0 },
-    { Format::ID::R32G32B32A32_UINT, GL_RGBA32UI, GL_RGBA32UI, GenerateMip<R32G32B32A32>, NoCopyFunctions, ReadColor<R32G32B32A32, GLuint>, WriteColor<R32G32B32A32, GLuint>, GL_UNSIGNED_INT, 32, 32, 32, 32, 0, 0 },
-    { Format::ID::R32G32B32_FLOAT, GL_RGB32F, GL_RGB32F, GenerateMip<R32G32B32F>, NoCopyFunctions, ReadColor<R32G32B32F, GLfloat>, WriteColor<R32G32B32F, GLfloat>, GL_FLOAT, 32, 32, 32, 0, 0, 0 },
-    { Format::ID::R32G32B32_SINT, GL_RGB32I, GL_RGB32I, GenerateMip<R32G32B32S>, NoCopyFunctions, ReadColor<R32G32B32S, GLint>, WriteColor<R32G32B32S, GLint>, GL_INT, 32, 32, 32, 0, 0, 0 },
-    { Format::ID::R32G32B32_UINT, GL_RGB32UI, GL_RGB32UI, GenerateMip<R32G32B32>, NoCopyFunctions, ReadColor<R32G32B32, GLuint>, WriteColor<R32G32B32, GLuint>, GL_UNSIGNED_INT, 32, 32, 32, 0, 0, 0 },
-    { Format::ID::R32G32_FLOAT, GL_RG32F, GL_RG32F, GenerateMip<R32G32F>, NoCopyFunctions, ReadColor<R32G32F, GLfloat>, WriteColor<R32G32F, GLfloat>, GL_FLOAT, 32, 32, 0, 0, 0, 0 },
-    { Format::ID::R32G32_SINT, GL_RG32I, GL_RG32I, GenerateMip<R32G32S>, NoCopyFunctions, ReadColor<R32G32S, GLint>, WriteColor<R32G32S, GLint>, GL_INT, 32, 32, 0, 0, 0, 0 },
-    { Format::ID::R32G32_UINT, GL_RG32UI, GL_RG32UI, GenerateMip<R32G32>, NoCopyFunctions, ReadColor<R32G32, GLuint>, WriteColor<R32G32, GLuint>, GL_UNSIGNED_INT, 32, 32, 0, 0, 0, 0 },
-    { Format::ID::R32_FLOAT, GL_R32F, GL_R32F, GenerateMip<R32F>, NoCopyFunctions, ReadColor<R32F, GLfloat>, WriteColor<R32F, GLfloat>, GL_FLOAT, 32, 0, 0, 0, 0, 0 },
-    { Format::ID::R32_SINT, GL_R32I, GL_R32I, GenerateMip<R32S>, NoCopyFunctions, ReadColor<R32S, GLint>, WriteColor<R32S, GLint>, GL_INT, 32, 0, 0, 0, 0, 0 },
-    { Format::ID::R32_UINT, GL_R32UI, GL_R32UI, GenerateMip<R32>, NoCopyFunctions, ReadColor<R32, GLuint>, WriteColor<R32, GLuint>, GL_UNSIGNED_INT, 32, 0, 0, 0, 0, 0 },
-    { Format::ID::R4G4B4A4_UNORM, GL_RGBA4, GL_RGBA4, GenerateMip<R4G4B4A4>, NoCopyFunctions, ReadColor<R4G4B4A4, GLfloat>, WriteColor<R4G4B4A4, GLfloat>, GL_UNSIGNED_NORMALIZED, 4, 4, 4, 4, 0, 0 },
-    { Format::ID::R5G5B5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, GenerateMip<R5G5B5A1>, NoCopyFunctions, ReadColor<R5G5B5A1, GLfloat>, WriteColor<R5G5B5A1, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 5, 5, 1, 0, 0 },
-    { Format::ID::R5G6B5_UNORM, GL_RGB565, GL_RGB565, GenerateMip<R5G6B5>, NoCopyFunctions, ReadColor<R5G6B5, GLfloat>, WriteColor<R5G6B5, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 6, 5, 0, 0, 0 },
-    { Format::ID::R8G8B8A8_SINT, GL_RGBA8I, GL_RGBA8I, GenerateMip<R8G8B8A8S>, NoCopyFunctions, ReadColor<R8G8B8A8S, GLint>, WriteColor<R8G8B8A8S, GLint>, GL_INT, 8, 8, 8, 8, 0, 0 },
-    { Format::ID::R8G8B8A8_SNORM, GL_RGBA8_SNORM, GL_RGBA8_SNORM, GenerateMip<R8G8B8A8S>, NoCopyFunctions, ReadColor<R8G8B8A8S, GLfloat>, WriteColor<R8G8B8A8S, GLfloat>, GL_SIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 },
-    { Format::ID::R8G8B8A8_TYPELESS, GL_RGBA8, GL_RGBA8, GenerateMip<R8G8B8A8>, NoCopyFunctions, ReadColor<R8G8B8A8, GLfloat>, WriteColor<R8G8B8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 },
-    { Format::ID::R8G8B8A8_TYPELESS_SRGB, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GenerateMip<R8G8B8A8>, NoCopyFunctions, ReadColor<R8G8B8A8, GLfloat>, WriteColor<R8G8B8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 },
-    { Format::ID::R8G8B8A8_UINT, GL_RGBA8UI, GL_RGBA8UI, GenerateMip<R8G8B8A8>, NoCopyFunctions, ReadColor<R8G8B8A8, GLuint>, WriteColor<R8G8B8A8, GLuint>, GL_UNSIGNED_INT, 8, 8, 8, 8, 0, 0 },
-    { Format::ID::R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, GenerateMip<R8G8B8A8>, NoCopyFunctions, ReadColor<R8G8B8A8, GLfloat>, WriteColor<R8G8B8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 },
-    { Format::ID::R8G8B8A8_UNORM_SRGB, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GenerateMip<R8G8B8A8SRGB>, NoCopyFunctions, ReadColor<R8G8B8A8SRGB, GLfloat>, WriteColor<R8G8B8A8SRGB, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 },
-    { Format::ID::R8G8B8_SINT, GL_RGB8I, GL_RGB8I, GenerateMip<R8G8B8S>, NoCopyFunctions, ReadColor<R8G8B8S, GLint>, WriteColor<R8G8B8S, GLint>, GL_INT, 8, 8, 8, 0, 0, 0 },
-    { Format::ID::R8G8B8_SNORM, GL_RGB8_SNORM, GL_RGB8_SNORM, GenerateMip<R8G8B8S>, NoCopyFunctions, ReadColor<R8G8B8S, GLfloat>, WriteColor<R8G8B8S, GLfloat>, GL_SIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0 },
-    { Format::ID::R8G8B8_UINT, GL_RGB8UI, GL_RGB8UI, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLuint>, WriteColor<R8G8B8, GLuint>, GL_UNSIGNED_INT, 8, 8, 8, 0, 0, 0 },
-    { Format::ID::R8G8B8_UNORM, GL_RGB8, GL_RGB8, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLfloat>, WriteColor<R8G8B8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0 },
-    { Format::ID::R8G8B8_UNORM_SRGB, GL_SRGB8, GL_SRGB8, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLfloat>, WriteColor<R8G8B8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0 },
-    { Format::ID::R8G8_SINT, GL_RG8I, GL_RG8I, GenerateMip<R8G8S>, NoCopyFunctions, ReadColor<R8G8S, GLint>, WriteColor<R8G8S, GLint>, GL_INT, 8, 8, 0, 0, 0, 0 },
-    { Format::ID::R8G8_SNORM, GL_RG8_SNORM, GL_RG8_SNORM, GenerateMip<R8G8S>, NoCopyFunctions, ReadColor<R8G8S, GLfloat>, WriteColor<R8G8S, GLfloat>, GL_SIGNED_NORMALIZED, 8, 8, 0, 0, 0, 0 },
-    { Format::ID::R8G8_UINT, GL_RG8UI, GL_RG8UI, GenerateMip<R8G8>, NoCopyFunctions, ReadColor<R8G8, GLuint>, WriteColor<R8G8, GLuint>, GL_UNSIGNED_INT, 8, 8, 0, 0, 0, 0 },
-    { Format::ID::R8G8_UNORM, GL_RG8, GL_RG8, GenerateMip<R8G8>, NoCopyFunctions, ReadColor<R8G8, GLfloat>, WriteColor<R8G8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 0, 0, 0, 0 },
-    { Format::ID::R8_SINT, GL_R8I, GL_R8I, GenerateMip<R8S>, NoCopyFunctions, ReadColor<R8S, GLint>, WriteColor<R8S, GLint>, GL_INT, 8, 0, 0, 0, 0, 0 },
-    { Format::ID::R8_SNORM, GL_R8_SNORM, GL_R8_SNORM, GenerateMip<R8S>, NoCopyFunctions, ReadColor<R8S, GLfloat>, WriteColor<R8S, GLfloat>, GL_SIGNED_NORMALIZED, 8, 0, 0, 0, 0, 0 },
-    { Format::ID::R8_UINT, GL_R8UI, GL_R8UI, GenerateMip<R8>, NoCopyFunctions, ReadColor<R8, GLuint>, WriteColor<R8, GLuint>, GL_UNSIGNED_INT, 8, 0, 0, 0, 0, 0 },
-    { Format::ID::R8_UNORM, GL_R8, GL_R8, GenerateMip<R8>, NoCopyFunctions, ReadColor<R8, GLfloat>, WriteColor<R8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 0, 0, 0, 0, 0 },
-    { Format::ID::R9G9B9E5_SHAREDEXP, GL_RGB9_E5, GL_RGB9_E5, GenerateMip<R9G9B9E5>, NoCopyFunctions, ReadColor<R9G9B9E5, GLfloat>, WriteColor<R9G9B9E5, GLfloat>, GL_FLOAT, 9, 9, 9, 0, 0, 0 },
-    { Format::ID::S8_UINT, GL_STENCIL_INDEX8, GL_STENCIL_INDEX8, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_INT, 0, 0, 0, 0, 0, 8 },
+    { Format::ID::NONE, GL_NONE, GL_NONE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_NONE, 0, 0, 0, 0, 0, 0, 0, false },
+    { Format::ID::A16_FLOAT, GL_ALPHA16F_EXT, GL_ALPHA16F_EXT, GenerateMip<A16F>, NoCopyFunctions, ReadColor<A16F, GLfloat>, WriteColor<A16F, GLfloat>, GL_FLOAT, 0, 0, 0, 16, 0, 0, 2, false },
+    { Format::ID::A1R5G5B5_UNORM, GL_A1RGB5_ANGLEX, GL_A1RGB5_ANGLEX, GenerateMip<A1R5G5B5>, NoCopyFunctions, ReadColor<A1R5G5B5, GLfloat>, WriteColor<A1R5G5B5, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 5, 5, 1, 0, 0, 2, false },
+    { Format::ID::A32_FLOAT, GL_ALPHA32F_EXT, GL_ALPHA32F_EXT, GenerateMip<A32F>, NoCopyFunctions, ReadColor<A32F, GLfloat>, WriteColor<A32F, GLfloat>, GL_FLOAT, 0, 0, 0, 32, 0, 0, 4, false },
+    { Format::ID::A8_UNORM, GL_ALPHA8_EXT, GL_ALPHA8_EXT, GenerateMip<A8>, NoCopyFunctions, ReadColor<A8, GLfloat>, WriteColor<A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 8, 0, 0, 1, false },
+    { Format::ID::ASTC_10x10_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_10x10_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_10x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_10x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_COMPRESSED_RGBA_ASTC_10x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_10x6_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_10x6_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_10x8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_10x8_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_COMPRESSED_RGBA_ASTC_10x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_12x10_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_12x10_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_COMPRESSED_RGBA_ASTC_12x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_12x12_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_12x12_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_4x4_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_4x4_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_5x4_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_5x4_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_5x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_5x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_6x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_6x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_6x6_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_6x6_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_8x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_8x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_8x6_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_8x6_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_COMPRESSED_RGBA_ASTC_8x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_8x8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::ASTC_8x8_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::B4G4R4A4_UNORM, GL_BGRA4_ANGLEX, GL_RGBA4, GenerateMip<A4R4G4B4>, NoCopyFunctions, ReadColor<A4R4G4B4, GLfloat>, WriteColor<A4R4G4B4, GLfloat>, GL_UNSIGNED_NORMALIZED, 4, 4, 4, 4, 0, 0, 2, false },
+    { Format::ID::B5G5R5A1_UNORM, GL_BGR5_A1_ANGLEX, GL_RGB5_A1, GenerateMip<A1R5G5B5>, NoCopyFunctions, ReadColor<A1R5G5B5, GLfloat>, WriteColor<A1R5G5B5, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 5, 5, 1, 0, 0, 2, false },
+    { Format::ID::B5G6R5_UNORM, GL_BGR565_ANGLEX, GL_RGB565, GenerateMip<B5G6R5>, NoCopyFunctions, ReadColor<B5G6R5, GLfloat>, WriteColor<B5G6R5, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 6, 5, 0, 0, 0, 2, false },
+    { Format::ID::B8G8R8A8_TYPELESS, GL_BGRA8_EXT, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, NoCopyFunctions, ReadColor<B8G8R8A8, GLfloat>, WriteColor<B8G8R8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 4, false },
+    { Format::ID::B8G8R8A8_TYPELESS_SRGB, GL_BGRA8_SRGB_ANGLEX, GL_BGRA8_SRGB_ANGLEX, GenerateMip<B8G8R8A8>, NoCopyFunctions, ReadColor<B8G8R8A8, GLfloat>, WriteColor<B8G8R8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 4, false },
+    { Format::ID::B8G8R8A8_UNORM, GL_BGRA8_EXT, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, BGRACopyFunctions, ReadColor<B8G8R8A8, GLfloat>, WriteColor<B8G8R8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 4, false },
+    { Format::ID::B8G8R8A8_UNORM_SRGB, GL_BGRA8_SRGB_ANGLEX, GL_BGRA8_SRGB_ANGLEX, GenerateMip<B8G8R8A8>, NoCopyFunctions, ReadColor<B8G8R8A8, GLfloat>, WriteColor<B8G8R8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 4, false },
+    { Format::ID::B8G8R8X8_UNORM, GL_BGRA8_EXT, GL_BGRA8_EXT, GenerateMip<B8G8R8X8>, NoCopyFunctions, ReadColor<B8G8R8X8, GLfloat>, WriteColor<B8G8R8X8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 3, false },
+    { Format::ID::BC1_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::BC1_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::BC1_RGB_UNORM_BLOCK, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::BC1_RGB_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::BC2_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::BC2_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::BC3_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::BC3_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
+    { Format::ID::D16_UNORM, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT16, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 16, 0, 2, false },
+    { Format::ID::D24_UNORM, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT24, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 24, 0, 3, false },
+    { Format::ID::D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 24, 8, 4, false },
+    { Format::ID::D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, nullptr, NoCopyFunctions, nullptr, nullptr, GL_FLOAT, 0, 0, 0, 0, 32, 0, 4, false },
+    { Format::ID::D32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, nullptr, NoCopyFunctions, nullptr, nullptr, GL_FLOAT, 0, 0, 0, 0, 32, 8, 5, false },
+    { Format::ID::D32_UNORM, GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT32_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 32, 0, 4, false },
+    { Format::ID::EAC_R11G11_SNORM_BLOCK, GL_COMPRESSED_SIGNED_RG11_EAC, GL_COMPRESSED_SIGNED_RG11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 11, 11, 0, 0, 0, 0, 2, true },
+    { Format::ID::EAC_R11G11_UNORM_BLOCK, GL_COMPRESSED_RG11_EAC, GL_COMPRESSED_RG11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 11, 11, 0, 0, 0, 0, 2, true },
+    { Format::ID::EAC_R11_SNORM_BLOCK, GL_COMPRESSED_SIGNED_R11_EAC, GL_COMPRESSED_SIGNED_R11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 11, 0, 0, 0, 0, 0, 1, true },
+    { Format::ID::EAC_R11_UNORM_BLOCK, GL_COMPRESSED_R11_EAC, GL_COMPRESSED_R11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 11, 0, 0, 0, 0, 0, 1, true },
+    { Format::ID::ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 3, true },
+    { Format::ID::ETC1_R8G8B8_UNORM_BLOCK, GL_ETC1_RGB8_OES, GL_ETC1_RGB8_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 3, true },
+    { Format::ID::ETC2_R8G8B8A1_SRGB_BLOCK, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 1, 0, 0, 3, true },
+    { Format::ID::ETC2_R8G8B8A1_UNORM_BLOCK, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 1, 0, 0, 3, true },
+    { Format::ID::ETC2_R8G8B8A8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 4, true },
+    { Format::ID::ETC2_R8G8B8A8_UNORM_BLOCK, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_RGBA8_ETC2_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 4, true },
+    { Format::ID::ETC2_R8G8B8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ETC2, GL_COMPRESSED_SRGB8_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 3, true },
+    { Format::ID::ETC2_R8G8B8_UNORM_BLOCK, GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_RGB8_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 3, true },
+    { Format::ID::L16A16_FLOAT, GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA16F_EXT, GenerateMip<L16A16F>, NoCopyFunctions, ReadColor<L16A16F, GLfloat>, WriteColor<L16A16F, GLfloat>, GL_FLOAT, 0, 0, 0, 16, 0, 0, 2, false },
+    { Format::ID::L16_FLOAT, GL_LUMINANCE16F_EXT, GL_LUMINANCE16F_EXT, GenerateMip<L16F>, NoCopyFunctions, ReadColor<L16F, GLfloat>, WriteColor<L16F, GLfloat>, GL_FLOAT, 0, 0, 0, 0, 0, 0, 0, false },
+    { Format::ID::L32A32_FLOAT, GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA32F_EXT, GenerateMip<L32A32F>, NoCopyFunctions, ReadColor<L32A32F, GLfloat>, WriteColor<L32A32F, GLfloat>, GL_FLOAT, 0, 0, 0, 32, 0, 0, 4, false },
+    { Format::ID::L32_FLOAT, GL_LUMINANCE32F_EXT, GL_LUMINANCE32F_EXT, GenerateMip<L32F>, NoCopyFunctions, ReadColor<L32F, GLfloat>, WriteColor<L32F, GLfloat>, GL_FLOAT, 0, 0, 0, 0, 0, 0, 0, false },
+    { Format::ID::L8A8_UNORM, GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip<L8A8>, NoCopyFunctions, ReadColor<L8A8, GLfloat>, WriteColor<L8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 8, 0, 0, 1, false },
+    { Format::ID::L8_UNORM, GL_LUMINANCE8_EXT, GL_LUMINANCE8_EXT, GenerateMip<L8>, NoCopyFunctions, ReadColor<L8, GLfloat>, WriteColor<L8, GLfloat>, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, false },
+    { Format::ID::R10G10B10A2_UINT, GL_RGB10_A2UI, GL_RGB10_A2UI, GenerateMip<R10G10B10A2>, NoCopyFunctions, ReadColor<R10G10B10A2, GLuint>, WriteColor<R10G10B10A2, GLuint>, GL_UNSIGNED_INT, 10, 10, 10, 2, 0, 0, 4, false },
+    { Format::ID::R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, GenerateMip<R10G10B10A2>, NoCopyFunctions, ReadColor<R10G10B10A2, GLfloat>, WriteColor<R10G10B10A2, GLfloat>, GL_UNSIGNED_NORMALIZED, 10, 10, 10, 2, 0, 0, 4, false },
+    { Format::ID::R11G11B10_FLOAT, GL_R11F_G11F_B10F, GL_R11F_G11F_B10F, GenerateMip<R11G11B10F>, NoCopyFunctions, ReadColor<R11G11B10F, GLfloat>, WriteColor<R11G11B10F, GLfloat>, GL_FLOAT, 11, 11, 10, 0, 0, 0, 4, false },
+    { Format::ID::R16G16B16A16_FLOAT, GL_RGBA16F, GL_RGBA16F, GenerateMip<R16G16B16A16F>, NoCopyFunctions, ReadColor<R16G16B16A16F, GLfloat>, WriteColor<R16G16B16A16F, GLfloat>, GL_FLOAT, 16, 16, 16, 16, 0, 0, 8, false },
+    { Format::ID::R16G16B16A16_SINT, GL_RGBA16I, GL_RGBA16I, GenerateMip<R16G16B16A16S>, NoCopyFunctions, ReadColor<R16G16B16A16S, GLint>, WriteColor<R16G16B16A16S, GLint>, GL_INT, 16, 16, 16, 16, 0, 0, 8, false },
+    { Format::ID::R16G16B16A16_SNORM, GL_RGBA16_SNORM_EXT, GL_RGBA16_SNORM_EXT, GenerateMip<R16G16B16A16S>, NoCopyFunctions, ReadColor<R16G16B16A16S, GLfloat>, WriteColor<R16G16B16A16S, GLfloat>, GL_SIGNED_NORMALIZED, 16, 16, 16, 16, 0, 0, 8, false },
+    { Format::ID::R16G16B16A16_UINT, GL_RGBA16UI, GL_RGBA16UI, GenerateMip<R16G16B16A16>, NoCopyFunctions, ReadColor<R16G16B16A16, GLuint>, WriteColor<R16G16B16A16, GLuint>, GL_UNSIGNED_INT, 16, 16, 16, 16, 0, 0, 8, false },
+    { Format::ID::R16G16B16A16_UNORM, GL_RGBA16_EXT, GL_RGBA16_EXT, GenerateMip<R16G16B16A16>, NoCopyFunctions, ReadColor<R16G16B16A16, GLfloat>, WriteColor<R16G16B16A16, GLfloat>, GL_UNSIGNED_NORMALIZED, 16, 16, 16, 16, 0, 0, 8, false },
+    { Format::ID::R16G16B16_FLOAT, GL_RGB16F, GL_RGB16F, GenerateMip<R16G16B16F>, NoCopyFunctions, ReadColor<R16G16B16F, GLfloat>, WriteColor<R16G16B16F, GLfloat>, GL_FLOAT, 16, 16, 16, 0, 0, 0, 6, false },
+    { Format::ID::R16G16B16_SINT, GL_RGB16I, GL_RGB16I, GenerateMip<R16G16B16S>, NoCopyFunctions, ReadColor<R16G16B16S, GLint>, WriteColor<R16G16B16S, GLint>, GL_INT, 16, 16, 16, 0, 0, 0, 6, false },
+    { Format::ID::R16G16B16_SNORM, GL_RGB16_SNORM_EXT, GL_RGB16_SNORM_EXT, GenerateMip<R16G16B16S>, NoCopyFunctions, ReadColor<R16G16B16S, GLfloat>, WriteColor<R16G16B16S, GLfloat>, GL_SIGNED_NORMALIZED, 16, 16, 16, 0, 0, 0, 6, false },
+    { Format::ID::R16G16B16_UINT, GL_RGB16UI, GL_RGB16UI, GenerateMip<R16G16B16>, NoCopyFunctions, ReadColor<R16G16B16, GLuint>, WriteColor<R16G16B16, GLuint>, GL_UNSIGNED_INT, 16, 16, 16, 0, 0, 0, 6, false },
+    { Format::ID::R16G16B16_UNORM, GL_RGB16_EXT, GL_RGB16_EXT, GenerateMip<R16G16B16>, NoCopyFunctions, ReadColor<R16G16B16, GLfloat>, WriteColor<R16G16B16, GLfloat>, GL_UNSIGNED_NORMALIZED, 16, 16, 16, 0, 0, 0, 6, false },
+    { Format::ID::R16G16_FLOAT, GL_RG16F, GL_RG16F, GenerateMip<R16G16F>, NoCopyFunctions, ReadColor<R16G16F, GLfloat>, WriteColor<R16G16F, GLfloat>, GL_FLOAT, 16, 16, 0, 0, 0, 0, 4, false },
+    { Format::ID::R16G16_SINT, GL_RG16I, GL_RG16I, GenerateMip<R16G16S>, NoCopyFunctions, ReadColor<R16G16S, GLint>, WriteColor<R16G16S, GLint>, GL_INT, 16, 16, 0, 0, 0, 0, 4, false },
+    { Format::ID::R16G16_SNORM, GL_RG16_SNORM_EXT, GL_RG16_SNORM_EXT, GenerateMip<R16G16S>, NoCopyFunctions, ReadColor<R16G16S, GLfloat>, WriteColor<R16G16S, GLfloat>, GL_SIGNED_NORMALIZED, 16, 16, 0, 0, 0, 0, 4, false },
+    { Format::ID::R16G16_UINT, GL_RG16UI, GL_RG16UI, GenerateMip<R16G16>, NoCopyFunctions, ReadColor<R16G16, GLuint>, WriteColor<R16G16, GLuint>, GL_UNSIGNED_INT, 16, 16, 0, 0, 0, 0, 4, false },
+    { Format::ID::R16G16_UNORM, GL_RG16_EXT, GL_RG16_EXT, GenerateMip<R16G16>, NoCopyFunctions, ReadColor<R16G16, GLfloat>, WriteColor<R16G16, GLfloat>, GL_UNSIGNED_NORMALIZED, 16, 16, 0, 0, 0, 0, 4, false },
+    { Format::ID::R16_FLOAT, GL_R16F, GL_R16F, GenerateMip<R16F>, NoCopyFunctions, ReadColor<R16F, GLfloat>, WriteColor<R16F, GLfloat>, GL_FLOAT, 16, 0, 0, 0, 0, 0, 2, false },
+    { Format::ID::R16_SINT, GL_R16I, GL_R16I, GenerateMip<R16S>, NoCopyFunctions, ReadColor<R16S, GLint>, WriteColor<R16S, GLint>, GL_INT, 16, 0, 0, 0, 0, 0, 2, false },
+    { Format::ID::R16_SNORM, GL_R16_SNORM_EXT, GL_R16_SNORM_EXT, GenerateMip<R16S>, NoCopyFunctions, ReadColor<R16S, GLfloat>, WriteColor<R16S, GLfloat>, GL_SIGNED_NORMALIZED, 16, 0, 0, 0, 0, 0, 2, false },
+    { Format::ID::R16_UINT, GL_R16UI, GL_R16UI, GenerateMip<R16>, NoCopyFunctions, ReadColor<R16, GLuint>, WriteColor<R16, GLuint>, GL_UNSIGNED_INT, 16, 0, 0, 0, 0, 0, 2, false },
+    { Format::ID::R16_UNORM, GL_R16_EXT, GL_R16_EXT, GenerateMip<R16>, NoCopyFunctions, ReadColor<R16, GLfloat>, WriteColor<R16, GLfloat>, GL_UNSIGNED_NORMALIZED, 16, 0, 0, 0, 0, 0, 2, false },
+    { Format::ID::R32G32B32A32_FLOAT, GL_RGBA32F, GL_RGBA32F, GenerateMip<R32G32B32A32F>, NoCopyFunctions, ReadColor<R32G32B32A32F, GLfloat>, WriteColor<R32G32B32A32F, GLfloat>, GL_FLOAT, 32, 32, 32, 32, 0, 0, 16, false },
+    { Format::ID::R32G32B32A32_SINT, GL_RGBA32I, GL_RGBA32I, GenerateMip<R32G32B32A32S>, NoCopyFunctions, ReadColor<R32G32B32A32S, GLint>, WriteColor<R32G32B32A32S, GLint>, GL_INT, 32, 32, 32, 32, 0, 0, 16, false },
+    { Format::ID::R32G32B32A32_UINT, GL_RGBA32UI, GL_RGBA32UI, GenerateMip<R32G32B32A32>, NoCopyFunctions, ReadColor<R32G32B32A32, GLuint>, WriteColor<R32G32B32A32, GLuint>, GL_UNSIGNED_INT, 32, 32, 32, 32, 0, 0, 16, false },
+    { Format::ID::R32G32B32_FLOAT, GL_RGB32F, GL_RGB32F, GenerateMip<R32G32B32F>, NoCopyFunctions, ReadColor<R32G32B32F, GLfloat>, WriteColor<R32G32B32F, GLfloat>, GL_FLOAT, 32, 32, 32, 0, 0, 0, 12, false },
+    { Format::ID::R32G32B32_SINT, GL_RGB32I, GL_RGB32I, GenerateMip<R32G32B32S>, NoCopyFunctions, ReadColor<R32G32B32S, GLint>, WriteColor<R32G32B32S, GLint>, GL_INT, 32, 32, 32, 0, 0, 0, 12, false },
+    { Format::ID::R32G32B32_UINT, GL_RGB32UI, GL_RGB32UI, GenerateMip<R32G32B32>, NoCopyFunctions, ReadColor<R32G32B32, GLuint>, WriteColor<R32G32B32, GLuint>, GL_UNSIGNED_INT, 32, 32, 32, 0, 0, 0, 12, false },
+    { Format::ID::R32G32_FLOAT, GL_RG32F, GL_RG32F, GenerateMip<R32G32F>, NoCopyFunctions, ReadColor<R32G32F, GLfloat>, WriteColor<R32G32F, GLfloat>, GL_FLOAT, 32, 32, 0, 0, 0, 0, 8, false },
+    { Format::ID::R32G32_SINT, GL_RG32I, GL_RG32I, GenerateMip<R32G32S>, NoCopyFunctions, ReadColor<R32G32S, GLint>, WriteColor<R32G32S, GLint>, GL_INT, 32, 32, 0, 0, 0, 0, 8, false },
+    { Format::ID::R32G32_UINT, GL_RG32UI, GL_RG32UI, GenerateMip<R32G32>, NoCopyFunctions, ReadColor<R32G32, GLuint>, WriteColor<R32G32, GLuint>, GL_UNSIGNED_INT, 32, 32, 0, 0, 0, 0, 8, false },
+    { Format::ID::R32_FLOAT, GL_R32F, GL_R32F, GenerateMip<R32F>, NoCopyFunctions, ReadColor<R32F, GLfloat>, WriteColor<R32F, GLfloat>, GL_FLOAT, 32, 0, 0, 0, 0, 0, 4, false },
+    { Format::ID::R32_SINT, GL_R32I, GL_R32I, GenerateMip<R32S>, NoCopyFunctions, ReadColor<R32S, GLint>, WriteColor<R32S, GLint>, GL_INT, 32, 0, 0, 0, 0, 0, 4, false },
+    { Format::ID::R32_UINT, GL_R32UI, GL_R32UI, GenerateMip<R32>, NoCopyFunctions, ReadColor<R32, GLuint>, WriteColor<R32, GLuint>, GL_UNSIGNED_INT, 32, 0, 0, 0, 0, 0, 4, false },
+    { Format::ID::R4G4B4A4_UNORM, GL_RGBA4, GL_RGBA4, GenerateMip<R4G4B4A4>, NoCopyFunctions, ReadColor<R4G4B4A4, GLfloat>, WriteColor<R4G4B4A4, GLfloat>, GL_UNSIGNED_NORMALIZED, 4, 4, 4, 4, 0, 0, 2, false },
+    { Format::ID::R5G5B5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, GenerateMip<R5G5B5A1>, NoCopyFunctions, ReadColor<R5G5B5A1, GLfloat>, WriteColor<R5G5B5A1, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 5, 5, 1, 0, 0, 2, false },
+    { Format::ID::R5G6B5_UNORM, GL_RGB565, GL_RGB565, GenerateMip<R5G6B5>, NoCopyFunctions, ReadColor<R5G6B5, GLfloat>, WriteColor<R5G6B5, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 6, 5, 0, 0, 0, 2, false },
+    { Format::ID::R8G8B8A8_SINT, GL_RGBA8I, GL_RGBA8I, GenerateMip<R8G8B8A8S>, NoCopyFunctions, ReadColor<R8G8B8A8S, GLint>, WriteColor<R8G8B8A8S, GLint>, GL_INT, 8, 8, 8, 8, 0, 0, 4, false },
+    { Format::ID::R8G8B8A8_SNORM, GL_RGBA8_SNORM, GL_RGBA8_SNORM, GenerateMip<R8G8B8A8S>, NoCopyFunctions, ReadColor<R8G8B8A8S, GLfloat>, WriteColor<R8G8B8A8S, GLfloat>, GL_SIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 4, false },
+    { Format::ID::R8G8B8A8_TYPELESS, GL_RGBA8, GL_RGBA8, GenerateMip<R8G8B8A8>, NoCopyFunctions, ReadColor<R8G8B8A8, GLfloat>, WriteColor<R8G8B8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 4, false },
+    { Format::ID::R8G8B8A8_TYPELESS_SRGB, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GenerateMip<R8G8B8A8>, NoCopyFunctions, ReadColor<R8G8B8A8, GLfloat>, WriteColor<R8G8B8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 4, false },
+    { Format::ID::R8G8B8A8_UINT, GL_RGBA8UI, GL_RGBA8UI, GenerateMip<R8G8B8A8>, NoCopyFunctions, ReadColor<R8G8B8A8, GLuint>, WriteColor<R8G8B8A8, GLuint>, GL_UNSIGNED_INT, 8, 8, 8, 8, 0, 0, 4, false },
+    { Format::ID::R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, GenerateMip<R8G8B8A8>, NoCopyFunctions, ReadColor<R8G8B8A8, GLfloat>, WriteColor<R8G8B8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 4, false },
+    { Format::ID::R8G8B8A8_UNORM_SRGB, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GenerateMip<R8G8B8A8SRGB>, NoCopyFunctions, ReadColor<R8G8B8A8SRGB, GLfloat>, WriteColor<R8G8B8A8SRGB, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 4, false },
+    { Format::ID::R8G8B8_SINT, GL_RGB8I, GL_RGB8I, GenerateMip<R8G8B8S>, NoCopyFunctions, ReadColor<R8G8B8S, GLint>, WriteColor<R8G8B8S, GLint>, GL_INT, 8, 8, 8, 0, 0, 0, 3, false },
+    { Format::ID::R8G8B8_SNORM, GL_RGB8_SNORM, GL_RGB8_SNORM, GenerateMip<R8G8B8S>, NoCopyFunctions, ReadColor<R8G8B8S, GLfloat>, WriteColor<R8G8B8S, GLfloat>, GL_SIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 3, false },
+    { Format::ID::R8G8B8_UINT, GL_RGB8UI, GL_RGB8UI, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLuint>, WriteColor<R8G8B8, GLuint>, GL_UNSIGNED_INT, 8, 8, 8, 0, 0, 0, 3, false },
+    { Format::ID::R8G8B8_UNORM, GL_RGB8, GL_RGB8, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLfloat>, WriteColor<R8G8B8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 3, false },
+    { Format::ID::R8G8B8_UNORM_SRGB, GL_SRGB8, GL_SRGB8, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLfloat>, WriteColor<R8G8B8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 3, false },
+    { Format::ID::R8G8_SINT, GL_RG8I, GL_RG8I, GenerateMip<R8G8S>, NoCopyFunctions, ReadColor<R8G8S, GLint>, WriteColor<R8G8S, GLint>, GL_INT, 8, 8, 0, 0, 0, 0, 2, false },
+    { Format::ID::R8G8_SNORM, GL_RG8_SNORM, GL_RG8_SNORM, GenerateMip<R8G8S>, NoCopyFunctions, ReadColor<R8G8S, GLfloat>, WriteColor<R8G8S, GLfloat>, GL_SIGNED_NORMALIZED, 8, 8, 0, 0, 0, 0, 2, false },
+    { Format::ID::R8G8_UINT, GL_RG8UI, GL_RG8UI, GenerateMip<R8G8>, NoCopyFunctions, ReadColor<R8G8, GLuint>, WriteColor<R8G8, GLuint>, GL_UNSIGNED_INT, 8, 8, 0, 0, 0, 0, 2, false },
+    { Format::ID::R8G8_UNORM, GL_RG8, GL_RG8, GenerateMip<R8G8>, NoCopyFunctions, ReadColor<R8G8, GLfloat>, WriteColor<R8G8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 0, 0, 0, 0, 2, false },
+    { Format::ID::R8_SINT, GL_R8I, GL_R8I, GenerateMip<R8S>, NoCopyFunctions, ReadColor<R8S, GLint>, WriteColor<R8S, GLint>, GL_INT, 8, 0, 0, 0, 0, 0, 1, false },
+    { Format::ID::R8_SNORM, GL_R8_SNORM, GL_R8_SNORM, GenerateMip<R8S>, NoCopyFunctions, ReadColor<R8S, GLfloat>, WriteColor<R8S, GLfloat>, GL_SIGNED_NORMALIZED, 8, 0, 0, 0, 0, 0, 1, false },
+    { Format::ID::R8_UINT, GL_R8UI, GL_R8UI, GenerateMip<R8>, NoCopyFunctions, ReadColor<R8, GLuint>, WriteColor<R8, GLuint>, GL_UNSIGNED_INT, 8, 0, 0, 0, 0, 0, 1, false },
+    { Format::ID::R8_UNORM, GL_R8, GL_R8, GenerateMip<R8>, NoCopyFunctions, ReadColor<R8, GLfloat>, WriteColor<R8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 0, 0, 0, 0, 0, 1, false },
+    { Format::ID::R9G9B9E5_SHAREDEXP, GL_RGB9_E5, GL_RGB9_E5, GenerateMip<R9G9B9E5>, NoCopyFunctions, ReadColor<R9G9B9E5, GLfloat>, WriteColor<R9G9B9E5, GLfloat>, GL_FLOAT, 9, 9, 9, 0, 0, 0, 3, false },
+    { Format::ID::S8_UINT, GL_STENCIL_INDEX8, GL_STENCIL_INDEX8, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_INT, 0, 0, 0, 0, 0, 8, 1, false },
     // clang-format on
 };
 
 // static
 Format::ID Format::InternalFormatToID(GLenum internalFormat)
 {
     switch (internalFormat)
     {
-        case GL_RGBA16_EXT:
-            return Format::ID::R16G16B16A16_UNORM;
-        case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
-            return Format::ID::ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK;
-        case GL_RG8I:
-            return Format::ID::R8G8_SINT;
-        case GL_R16F:
-            return Format::ID::R16_FLOAT;
-        case GL_RGBA8I:
-            return Format::ID::R8G8B8A8_SINT;
-        case GL_RG8UI:
-            return Format::ID::R8G8_UINT;
-        case GL_RGBA8_SNORM:
-            return Format::ID::R8G8B8A8_SNORM;
+        case GL_A1RGB5_ANGLEX:
+            return Format::ID::A1R5G5B5_UNORM;
+        case GL_ALPHA16F_EXT:
+            return Format::ID::A16_FLOAT;
+        case GL_ALPHA32F_EXT:
+            return Format::ID::A32_FLOAT;
+        case GL_ALPHA8_EXT:
+            return Format::ID::A8_UNORM;
+        case GL_BGR565_ANGLEX:
+            return Format::ID::B5G6R5_UNORM;
+        case GL_BGR5_A1_ANGLEX:
+            return Format::ID::B5G5R5A1_UNORM;
+        case GL_BGRA4_ANGLEX:
+            return Format::ID::B4G4R4A4_UNORM;
+        case GL_BGRA8_EXT:
+            return Format::ID::B8G8R8A8_UNORM;
+        case GL_BGRA8_SRGB_ANGLEX:
+            return Format::ID::B8G8R8A8_UNORM_SRGB;
+        case GL_BGRA8_TYPELESS_ANGLEX:
+            return Format::ID::B8G8R8A8_TYPELESS;
+        case GL_BGRA8_TYPELESS_SRGB_ANGLEX:
+            return Format::ID::B8G8R8A8_TYPELESS_SRGB;
+        case GL_BGRX8_ANGLEX:
+            return Format::ID::B8G8R8X8_UNORM;
+        case GL_COMPRESSED_R11_EAC:
+            return Format::ID::EAC_R11_UNORM_BLOCK;
+        case GL_COMPRESSED_RG11_EAC:
+            return Format::ID::EAC_R11G11_UNORM_BLOCK;
+        case GL_COMPRESSED_RGB8_ETC2:
+            return Format::ID::ETC2_R8G8B8_UNORM_BLOCK;
+        case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+            return Format::ID::ETC2_R8G8B8A1_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA8_ETC2_EAC:
+            return Format::ID::ETC2_R8G8B8A8_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
+            return Format::ID::ASTC_10x10_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
+            return Format::ID::ASTC_10x5_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
+            return Format::ID::ASTC_10x6_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
+            return Format::ID::ASTC_10x8_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
+            return Format::ID::ASTC_12x10_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
+            return Format::ID::ASTC_12x12_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
+            return Format::ID::ASTC_4x4_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
+            return Format::ID::ASTC_5x4_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
+            return Format::ID::ASTC_5x5_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
+            return Format::ID::ASTC_6x5_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
+            return Format::ID::ASTC_6x6_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
+            return Format::ID::ASTC_8x5_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
+            return Format::ID::ASTC_8x6_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
+            return Format::ID::ASTC_8x8_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+            return Format::ID::BC1_RGBA_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
+            return Format::ID::BC2_RGBA_UNORM_BLOCK;
+        case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
+            return Format::ID::BC3_RGBA_UNORM_BLOCK;
+        case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+            return Format::ID::BC1_RGB_UNORM_BLOCK;
+        case GL_COMPRESSED_SIGNED_R11_EAC:
+            return Format::ID::EAC_R11_SNORM_BLOCK;
+        case GL_COMPRESSED_SIGNED_RG11_EAC:
+            return Format::ID::EAC_R11G11_SNORM_BLOCK;
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
+            return Format::ID::ASTC_10x10_SRGB_BLOCK;
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
+            return Format::ID::ASTC_10x5_SRGB_BLOCK;
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
+            return Format::ID::ASTC_10x6_SRGB_BLOCK;
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
+            return Format::ID::ASTC_10x8_SRGB_BLOCK;
         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
             return Format::ID::ASTC_12x10_SRGB_BLOCK;
-        case GL_RG8_SNORM:
-            return Format::ID::R8G8_SNORM;
-        case GL_BGR565_ANGLEX:
-            return Format::ID::B5G6R5_UNORM;
-        case GL_DEPTH_COMPONENT24:
-            return Format::ID::D24_UNORM;
-        case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-            return Format::ID::ETC2_R8G8B8A1_UNORM_BLOCK;
-        case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
-            return Format::ID::ASTC_10x10_UNORM_BLOCK;
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
-            return Format::ID::ASTC_8x6_SRGB_BLOCK;
-        case GL_RGB32UI:
-            return Format::ID::R32G32B32_UINT;
-        case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
-            return Format::ID::ASTC_6x5_UNORM_BLOCK;
-        case GL_ALPHA32F_EXT:
-            return Format::ID::A32_FLOAT;
-        case GL_R16UI:
-            return Format::ID::R16_UINT;
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
+            return Format::ID::ASTC_12x12_SRGB_BLOCK;
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
+            return Format::ID::ASTC_4x4_SRGB_BLOCK;
         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
             return Format::ID::ASTC_5x4_SRGB_BLOCK;
         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
             return Format::ID::ASTC_5x5_SRGB_BLOCK;
-        case GL_COMPRESSED_R11_EAC:
-            return Format::ID::EAC_R11_UNORM_BLOCK;
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
-            return Format::ID::ASTC_10x10_SRGB_BLOCK;
-        case GL_RGBA32UI:
-            return Format::ID::R32G32B32A32_UINT;
-        case GL_R8_SNORM:
-            return Format::ID::R8_SNORM;
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
+            return Format::ID::ASTC_6x5_SRGB_BLOCK;
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
+            return Format::ID::ASTC_6x6_SRGB_BLOCK;
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
+            return Format::ID::ASTC_8x5_SRGB_BLOCK;
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
+            return Format::ID::ASTC_8x6_SRGB_BLOCK;
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
+            return Format::ID::ASTC_8x8_SRGB_BLOCK;
+        case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+            return Format::ID::ETC2_R8G8B8A8_SRGB_BLOCK;
+        case GL_COMPRESSED_SRGB8_ETC2:
+            return Format::ID::ETC2_R8G8B8_SRGB_BLOCK;
+        case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+            return Format::ID::ETC2_R8G8B8A1_SRGB_BLOCK;
         case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
             return Format::ID::BC1_RGBA_UNORM_SRGB_BLOCK;
+        case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+            return Format::ID::BC2_RGBA_UNORM_SRGB_BLOCK;
+        case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+            return Format::ID::BC3_RGBA_UNORM_SRGB_BLOCK;
+        case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+            return Format::ID::BC1_RGB_UNORM_SRGB_BLOCK;
+        case GL_DEPTH24_STENCIL8:
+            return Format::ID::D24_UNORM_S8_UINT;
+        case GL_DEPTH32F_STENCIL8:
+            return Format::ID::D32_FLOAT_S8X24_UINT;
+        case GL_DEPTH_COMPONENT16:
+            return Format::ID::D16_UNORM;
+        case GL_DEPTH_COMPONENT24:
+            return Format::ID::D24_UNORM;
+        case GL_DEPTH_COMPONENT32F:
+            return Format::ID::D32_FLOAT;
+        case GL_DEPTH_COMPONENT32_OES:
+            return Format::ID::D32_UNORM;
+        case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
+            return Format::ID::ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK;
+        case GL_ETC1_RGB8_OES:
+            return Format::ID::ETC1_R8G8B8_UNORM_BLOCK;
+        case GL_LUMINANCE16F_EXT:
+            return Format::ID::L16_FLOAT;
         case GL_LUMINANCE32F_EXT:
             return Format::ID::L32_FLOAT;
+        case GL_LUMINANCE8_ALPHA8_EXT:
+            return Format::ID::L8A8_UNORM;
+        case GL_LUMINANCE8_EXT:
+            return Format::ID::L8_UNORM;
+        case GL_LUMINANCE_ALPHA16F_EXT:
+            return Format::ID::L16A16_FLOAT;
+        case GL_LUMINANCE_ALPHA32F_EXT:
+            return Format::ID::L32A32_FLOAT;
+        case GL_NONE:
+            return Format::ID::NONE;
+        case GL_R11F_G11F_B10F:
+            return Format::ID::R11G11B10_FLOAT;
+        case GL_R16F:
+            return Format::ID::R16_FLOAT;
+        case GL_R16I:
+            return Format::ID::R16_SINT;
+        case GL_R16UI:
+            return Format::ID::R16_UINT;
+        case GL_R16_EXT:
+            return Format::ID::R16_UNORM;
+        case GL_R16_SNORM_EXT:
+            return Format::ID::R16_SNORM;
+        case GL_R32F:
+            return Format::ID::R32_FLOAT;
+        case GL_R32I:
+            return Format::ID::R32_SINT;
+        case GL_R32UI:
+            return Format::ID::R32_UINT;
+        case GL_R8:
+            return Format::ID::R8_UNORM;
+        case GL_R8I:
+            return Format::ID::R8_SINT;
+        case GL_R8UI:
+            return Format::ID::R8_UINT;
+        case GL_R8_SNORM:
+            return Format::ID::R8_SNORM;
+        case GL_RG16F:
+            return Format::ID::R16G16_FLOAT;
+        case GL_RG16I:
+            return Format::ID::R16G16_SINT;
+        case GL_RG16UI:
+            return Format::ID::R16G16_UINT;
         case GL_RG16_EXT:
             return Format::ID::R16G16_UNORM;
-        case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-            return Format::ID::ETC2_R8G8B8A1_SRGB_BLOCK;
-        case GL_SRGB8:
-            return Format::ID::R8G8B8_UNORM_SRGB;
-        case GL_LUMINANCE8_ALPHA8_EXT:
-            return Format::ID::L8A8_UNORM;
-        case GL_BGRX8_ANGLEX:
-            return Format::ID::B8G8R8X8_UNORM;
+        case GL_RG16_SNORM_EXT:
+            return Format::ID::R16G16_SNORM;
+        case GL_RG32F:
+            return Format::ID::R32G32_FLOAT;
+        case GL_RG32I:
+            return Format::ID::R32G32_SINT;
+        case GL_RG32UI:
+            return Format::ID::R32G32_UINT;
+        case GL_RG8:
+            return Format::ID::R8G8_UNORM;
+        case GL_RG8I:
+            return Format::ID::R8G8_SINT;
+        case GL_RG8UI:
+            return Format::ID::R8G8_UINT;
+        case GL_RG8_SNORM:
+            return Format::ID::R8G8_SNORM;
+        case GL_RGB:
+            return Format::ID::R8G8B8_UNORM;
+        case GL_RGB10_A2:
+            return Format::ID::R10G10B10A2_UNORM;
+        case GL_RGB10_A2UI:
+            return Format::ID::R10G10B10A2_UINT;
+        case GL_RGB16F:
+            return Format::ID::R16G16B16_FLOAT;
+        case GL_RGB16I:
+            return Format::ID::R16G16B16_SINT;
+        case GL_RGB16UI:
+            return Format::ID::R16G16B16_UINT;
+        case GL_RGB16_EXT:
+            return Format::ID::R16G16B16_UNORM;
         case GL_RGB16_SNORM_EXT:
             return Format::ID::R16G16B16_SNORM;
-        case GL_BGRA8_TYPELESS_SRGB_ANGLEX:
-            return Format::ID::B8G8R8A8_TYPELESS_SRGB;
-        case GL_RGBA8UI:
-            return Format::ID::R8G8B8A8_UINT;
-        case GL_BGRA4_ANGLEX:
-            return Format::ID::B4G4R4A4_UNORM;
-        case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
-            return Format::ID::ETC2_R8G8B8A8_SRGB_BLOCK;
-        case GL_LUMINANCE8_EXT:
-            return Format::ID::L8_UNORM;
-        case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
-            return Format::ID::BC3_RGBA_UNORM_BLOCK;
-        case GL_R16I:
-            return Format::ID::R16_SINT;
-        case GL_BGRA8_TYPELESS_ANGLEX:
-            return Format::ID::B8G8R8A8_TYPELESS;
+        case GL_RGB32F:
+            return Format::ID::R32G32B32_FLOAT;
+        case GL_RGB32I:
+            return Format::ID::R32G32B32_SINT;
+        case GL_RGB32UI:
+            return Format::ID::R32G32B32_UINT;
+        case GL_RGB565:
+            return Format::ID::R5G6B5_UNORM;
         case GL_RGB5_A1:
             return Format::ID::R5G5B5A1_UNORM;
-        case GL_RGB16UI:
-            return Format::ID::R16G16B16_UINT;
-        case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
-            return Format::ID::ASTC_4x4_UNORM_BLOCK;
-        case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
-            return Format::ID::BC2_RGBA_UNORM_SRGB_BLOCK;
-        case GL_R16_SNORM_EXT:
-            return Format::ID::R16_SNORM;
-        case GL_COMPRESSED_RGB8_ETC2:
-            return Format::ID::ETC2_R8G8B8_UNORM_BLOCK;
-        case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
-            return Format::ID::BC1_RGB_UNORM_SRGB_BLOCK;
+        case GL_RGB8:
+            return Format::ID::R8G8B8_UNORM;
+        case GL_RGB8I:
+            return Format::ID::R8G8B8_SINT;
+        case GL_RGB8UI:
+            return Format::ID::R8G8B8_UINT;
+        case GL_RGB8_SNORM:
+            return Format::ID::R8G8B8_SNORM;
+        case GL_RGB9_E5:
+            return Format::ID::R9G9B9E5_SHAREDEXP;
+        case GL_RGBA:
+            return Format::ID::R8G8B8A8_UNORM;
+        case GL_RGBA16F:
+            return Format::ID::R16G16B16A16_FLOAT;
+        case GL_RGBA16I:
+            return Format::ID::R16G16B16A16_SINT;
+        case GL_RGBA16UI:
+            return Format::ID::R16G16B16A16_UINT;
+        case GL_RGBA16_EXT:
+            return Format::ID::R16G16B16A16_UNORM;
+        case GL_RGBA16_SNORM_EXT:
+            return Format::ID::R16G16B16A16_SNORM;
         case GL_RGBA32F:
             return Format::ID::R32G32B32A32_FLOAT;
         case GL_RGBA32I:
             return Format::ID::R32G32B32A32_SINT;
-        case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
-            return Format::ID::BC3_RGBA_UNORM_SRGB_BLOCK;
-        case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
-            return Format::ID::ASTC_8x5_UNORM_BLOCK;
-        case GL_RG8:
-            return Format::ID::R8G8_UNORM;
-        case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
-            return Format::ID::ASTC_8x8_UNORM_BLOCK;
-        case GL_RGB10_A2:
-            return Format::ID::R10G10B10A2_UNORM;
-        case GL_COMPRESSED_SIGNED_RG11_EAC:
-            return Format::ID::EAC_R11G11_SNORM_BLOCK;
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
-            return Format::ID::ASTC_6x6_SRGB_BLOCK;
-        case GL_DEPTH_COMPONENT16:
-            return Format::ID::D16_UNORM;
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
-            return Format::ID::ASTC_10x5_SRGB_BLOCK;
-        case GL_RGB32I:
-            return Format::ID::R32G32B32_SINT;
-        case GL_R8:
-            return Format::ID::R8_UNORM;
-        case GL_RGB32F:
-            return Format::ID::R32G32B32_FLOAT;
-        case GL_RGBA8_TYPELESS_SRGB_ANGLEX:
-            return Format::ID::R8G8B8A8_TYPELESS_SRGB;
-        case GL_R16_EXT:
-            return Format::ID::R16_UNORM;
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
-            return Format::ID::ASTC_8x8_SRGB_BLOCK;
-        case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
-            return Format::ID::ASTC_10x5_UNORM_BLOCK;
-        case GL_R11F_G11F_B10F:
-            return Format::ID::R11G11B10_FLOAT;
-        case GL_RGB8:
-            return Format::ID::R8G8B8_UNORM;
-        case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
-            return Format::ID::ASTC_5x5_UNORM_BLOCK;
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
-            return Format::ID::ASTC_8x5_SRGB_BLOCK;
-        case GL_RGBA16I:
-            return Format::ID::R16G16B16A16_SINT;
-        case GL_R8I:
-            return Format::ID::R8_SINT;
-        case GL_RGB8_SNORM:
-            return Format::ID::R8G8B8_SNORM;
-        case GL_RG32F:
-            return Format::ID::R32G32_FLOAT;
-        case GL_DEPTH_COMPONENT32F:
-            return Format::ID::D32_FLOAT;
-        case GL_RG32I:
-            return Format::ID::R32G32_SINT;
-        case GL_ALPHA8_EXT:
-            return Format::ID::A8_UNORM;
-        case GL_RGB16_EXT:
-            return Format::ID::R16G16B16_UNORM;
-        case GL_BGRA8_EXT:
-            return Format::ID::B8G8R8A8_UNORM;
-        case GL_RG32UI:
-            return Format::ID::R32G32_UINT;
-        case GL_RGBA16UI:
-            return Format::ID::R16G16B16A16_UINT;
-        case GL_COMPRESSED_RGBA8_ETC2_EAC:
-            return Format::ID::ETC2_R8G8B8A8_UNORM_BLOCK;
-        case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-            return Format::ID::BC1_RGBA_UNORM_BLOCK;
-        case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
-            return Format::ID::ASTC_10x6_UNORM_BLOCK;
-        case GL_COMPRESSED_SRGB8_ETC2:
-            return Format::ID::ETC2_R8G8B8_SRGB_BLOCK;
-        case GL_BGRA8_SRGB_ANGLEX:
-            return Format::ID::B8G8R8A8_UNORM_SRGB;
-        case GL_DEPTH32F_STENCIL8:
-            return Format::ID::D32_FLOAT_S8X24_UINT;
-        case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
-            return Format::ID::ASTC_6x6_UNORM_BLOCK;
-        case GL_R32UI:
-            return Format::ID::R32_UINT;
-        case GL_BGR5_A1_ANGLEX:
-            return Format::ID::B5G5R5A1_UNORM;
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
-            return Format::ID::ASTC_12x12_SRGB_BLOCK;
-        case GL_COMPRESSED_RG11_EAC:
-            return Format::ID::EAC_R11G11_UNORM_BLOCK;
-        case GL_SRGB8_ALPHA8:
-            return Format::ID::R8G8B8A8_UNORM_SRGB;
-        case GL_LUMINANCE_ALPHA16F_EXT:
-            return Format::ID::L16A16_FLOAT;
-        case GL_RGBA:
-            return Format::ID::R8G8B8A8_UNORM;
-        case GL_ETC1_RGB8_OES:
-            return Format::ID::ETC1_R8G8B8_UNORM_BLOCK;
-        case GL_DEPTH24_STENCIL8:
-            return Format::ID::D24_UNORM_S8_UINT;
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
-            return Format::ID::ASTC_4x4_SRGB_BLOCK;
-        case GL_RGB16I:
-            return Format::ID::R16G16B16_SINT;
-        case GL_R8UI:
-            return Format::ID::R8_UINT;
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
-            return Format::ID::ASTC_10x6_SRGB_BLOCK;
-        case GL_RGBA16F:
-            return Format::ID::R16G16B16A16_FLOAT;
-        case GL_COMPRESSED_SIGNED_R11_EAC:
-            return Format::ID::EAC_R11_SNORM_BLOCK;
-        case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-            return Format::ID::BC1_RGB_UNORM_BLOCK;
-        case GL_RGB8I:
-            return Format::ID::R8G8B8_SINT;
-        case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
-            return Format::ID::ASTC_8x6_UNORM_BLOCK;
-        case GL_STENCIL_INDEX8:
-            return Format::ID::S8_UINT;
-        case GL_LUMINANCE_ALPHA32F_EXT:
-            return Format::ID::L32A32_FLOAT;
-        case GL_ALPHA16F_EXT:
-            return Format::ID::A16_FLOAT;
-        case GL_RGB8UI:
-            return Format::ID::R8G8B8_UINT;
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
-            return Format::ID::ASTC_10x8_SRGB_BLOCK;
-        case GL_RGBA8_TYPELESS_ANGLEX:
-            return Format::ID::R8G8B8A8_TYPELESS;
-        case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
-            return Format::ID::ASTC_12x10_UNORM_BLOCK;
-        case GL_RGB9_E5:
-            return Format::ID::R9G9B9E5_SHAREDEXP;
-        case GL_RGBA16_SNORM_EXT:
-            return Format::ID::R16G16B16A16_SNORM;
-        case GL_R32I:
-            return Format::ID::R32_SINT;
-        case GL_DEPTH_COMPONENT32_OES:
-            return Format::ID::D32_UNORM;
-        case GL_R32F:
-            return Format::ID::R32_FLOAT;
-        case GL_NONE:
-            return Format::ID::NONE;
-        case GL_RG16F:
-            return Format::ID::R16G16_FLOAT;
-        case GL_RGB:
-            return Format::ID::R8G8B8_UNORM;
-        case GL_RGB565:
-            return Format::ID::R5G6B5_UNORM;
-        case GL_LUMINANCE16F_EXT:
-            return Format::ID::L16_FLOAT;
-        case GL_RG16UI:
-            return Format::ID::R16G16_UINT;
-        case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
-            return Format::ID::BC2_RGBA_UNORM_BLOCK;
-        case GL_RG16I:
-            return Format::ID::R16G16_SINT;
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
-            return Format::ID::ASTC_6x5_SRGB_BLOCK;
-        case GL_RG16_SNORM_EXT:
-            return Format::ID::R16G16_SNORM;
-        case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
-            return Format::ID::ASTC_12x12_UNORM_BLOCK;
-        case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
-            return Format::ID::ASTC_5x4_UNORM_BLOCK;
-        case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
-            return Format::ID::ASTC_10x8_UNORM_BLOCK;
+        case GL_RGBA32UI:
+            return Format::ID::R32G32B32A32_UINT;
         case GL_RGBA4:
             return Format::ID::R4G4B4A4_UNORM;
         case GL_RGBA8:
             return Format::ID::R8G8B8A8_UNORM;
-        case GL_RGB16F:
-            return Format::ID::R16G16B16_FLOAT;
-        case GL_RGB10_A2UI:
-            return Format::ID::R10G10B10A2_UINT;
+        case GL_RGBA8I:
+            return Format::ID::R8G8B8A8_SINT;
+        case GL_RGBA8UI:
+            return Format::ID::R8G8B8A8_UINT;
+        case GL_RGBA8_SNORM:
+            return Format::ID::R8G8B8A8_SNORM;
+        case GL_RGBA8_TYPELESS_ANGLEX:
+            return Format::ID::R8G8B8A8_TYPELESS;
+        case GL_RGBA8_TYPELESS_SRGB_ANGLEX:
+            return Format::ID::R8G8B8A8_TYPELESS_SRGB;
+        case GL_SRGB8:
+            return Format::ID::R8G8B8_UNORM_SRGB;
+        case GL_SRGB8_ALPHA8:
+            return Format::ID::R8G8B8A8_UNORM_SRGB;
+        case GL_STENCIL_INDEX8:
+            return Format::ID::S8_UINT;
         default:
             return Format::ID::NONE;
     }
 }
 
 // static
 const Format &Format::Get(ID id)
 {
--- a/gfx/angle/checkout/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h
@@ -7,21 +7,22 @@
 //   Common ancenstor for all implementations of FBO attachable-objects.
 //   This means Surfaces, Textures and Renderbuffers.
 //
 
 #ifndef LIBANGLE_RENDERER_FRAMEBUFFER_ATTACHMENT_OBJECT_IMPL_H_
 #define LIBANGLE_RENDERER_FRAMEBUFFER_ATTACHMENT_OBJECT_IMPL_H_
 
 #include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Observer.h"
 
 namespace rx
 {
 
-class FramebufferAttachmentObjectImpl : angle::NonCopyable
+class FramebufferAttachmentObjectImpl : public angle::Subject
 {
   public:
     FramebufferAttachmentObjectImpl() {}
     virtual ~FramebufferAttachmentObjectImpl() {}
 
     virtual gl::Error getAttachmentRenderTarget(const gl::Context *context,
                                                 GLenum binding,
                                                 const gl::ImageIndex &imageIndex,
--- a/gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.h
@@ -75,18 +75,18 @@ class FramebufferImpl : angle::NonCopyab
     virtual gl::Error blit(const gl::Context *context,
                            const gl::Rectangle &sourceArea,
                            const gl::Rectangle &destArea,
                            GLbitfield mask,
                            GLenum filter) = 0;
 
     virtual bool checkStatus(const gl::Context *context) const = 0;
 
-    virtual void syncState(const gl::Context *context,
-                           const gl::Framebuffer::DirtyBits &dirtyBits) = 0;
+    virtual gl::Error syncState(const gl::Context *context,
+                                const gl::Framebuffer::DirtyBits &dirtyBits) = 0;
 
     virtual gl::Error getSamplePosition(size_t index, GLfloat *xy) const = 0;
 
     const gl::FramebufferState &getState() const { return mState; }
 
   protected:
     const gl::FramebufferState &mState;
 };
--- a/gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.h
@@ -30,17 +30,17 @@ struct BlockMemberInfo;
 
 namespace rx
 {
 class ProgramImpl : angle::NonCopyable
 {
   public:
     ProgramImpl(const gl::ProgramState &state) : mState(state) {}
     virtual ~ProgramImpl() {}
-    virtual void destroy(const gl::Context *context) {}
+    virtual gl::Error destroy(const gl::Context *context) { return gl::NoError(); }
 
     virtual gl::LinkResult load(const gl::Context *context,
                                 gl::InfoLog &infoLog,
                                 gl::BinaryInputStream *stream) = 0;
     virtual void save(const gl::Context *context, gl::BinaryOutputStream *stream) = 0;
     virtual void setBinaryRetrievableHint(bool retrievable) = 0;
     virtual void setSeparable(bool separable)               = 0;
 
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/RenderTargetCache.h
@@ -0,0 +1,160 @@
+//
+// 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.
+//
+// RenderTargetCache:
+// The RenderTargetCache pattern is used in the D3D9, D3D11 and Vulkan back-ends. It is a
+// cache of the various back-end objects (RenderTargets) associated with each Framebuffer
+// attachment, be they Textures, Renderbuffers, or Surfaces. The cache is updated in Framebuffer's
+// syncState method.
+//
+
+#ifndef LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_
+#define LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_
+
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+
+namespace rx
+{
+
+template <typename RenderTargetT>
+class RenderTargetCache final : angle::NonCopyable
+{
+  public:
+    RenderTargetCache();
+    ~RenderTargetCache();
+
+    gl::Error update(const gl::Context *context,
+                     const gl::FramebufferState &state,
+                     const gl::Framebuffer::DirtyBits &dirtyBits);
+
+    using RenderTargetArray = gl::AttachmentArray<RenderTargetT *>;
+
+    const RenderTargetArray &getColors() const;
+    RenderTargetT *getDepthStencil() const;
+
+    RenderTargetT *getColorRead(const gl::FramebufferState &state) const;
+
+  private:
+    gl::Error updateCachedRenderTarget(const gl::Context *context,
+                                       const gl::FramebufferAttachment *attachment,
+                                       RenderTargetT **cachedRenderTarget);
+
+    gl::Error updateColorRenderTarget(const gl::Context *context,
+                                      const gl::FramebufferState &state,
+                                      size_t colorIndex);
+    gl::Error updateDepthStencilRenderTarget(const gl::Context *context,
+                                             const gl::FramebufferState &state);
+
+    gl::AttachmentArray<RenderTargetT *> mColorRenderTargets;
+    // We only support a single Depth/Stencil RenderTarget currently.
+    RenderTargetT *mDepthStencilRenderTarget;
+};
+
+template <typename RenderTargetT>
+RenderTargetCache<RenderTargetT>::RenderTargetCache()
+    : mColorRenderTargets{{nullptr}}, mDepthStencilRenderTarget(nullptr)
+{
+}
+
+template <typename RenderTargetT>
+RenderTargetCache<RenderTargetT>::~RenderTargetCache()
+{
+}
+
+template <typename RenderTargetT>
+gl::Error RenderTargetCache<RenderTargetT>::update(const gl::Context *context,
+                                                   const gl::FramebufferState &state,
+                                                   const gl::Framebuffer::DirtyBits &dirtyBits)
+{
+    for (auto dirtyBit : dirtyBits)
+    {
+        switch (dirtyBit)
+        {
+            case gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT:
+            case gl::Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT:
+                ANGLE_TRY(updateDepthStencilRenderTarget(context, state));
+                break;
+            case gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS:
+            case gl::Framebuffer::DIRTY_BIT_READ_BUFFER:
+            case gl::Framebuffer::DIRTY_BIT_DEFAULT_WIDTH:
+            case gl::Framebuffer::DIRTY_BIT_DEFAULT_HEIGHT:
+            case gl::Framebuffer::DIRTY_BIT_DEFAULT_SAMPLES:
+            case gl::Framebuffer::DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS:
+                break;
+            default:
+            {
+                ASSERT(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0 &&
+                       dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX);
+                size_t colorIndex =
+                    static_cast<size_t>(dirtyBit - gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0);
+                ANGLE_TRY(updateColorRenderTarget(context, state, colorIndex));
+                break;
+            }
+        }
+    }
+
+    return gl::NoError();
+}
+
+template <typename RenderTargetT>
+const gl::AttachmentArray<RenderTargetT *> &RenderTargetCache<RenderTargetT>::getColors() const
+{
+    return mColorRenderTargets;
+}
+
+template <typename RenderTargetT>
+RenderTargetT *RenderTargetCache<RenderTargetT>::getDepthStencil() const
+{
+    return mDepthStencilRenderTarget;
+}
+
+template <typename RenderTargetT>
+gl::Error RenderTargetCache<RenderTargetT>::updateColorRenderTarget(
+    const gl::Context *context,
+    const gl::FramebufferState &state,
+    size_t colorIndex)
+{
+    return updateCachedRenderTarget(context, state.getColorAttachment(colorIndex),
+                                    &mColorRenderTargets[colorIndex]);
+}
+
+template <typename RenderTargetT>
+gl::Error RenderTargetCache<RenderTargetT>::updateDepthStencilRenderTarget(
+    const gl::Context *context,
+    const gl::FramebufferState &state)
+{
+    return updateCachedRenderTarget(context, state.getDepthOrStencilAttachment(),
+                                    &mDepthStencilRenderTarget);
+}
+
+template <typename RenderTargetT>
+gl::Error RenderTargetCache<RenderTargetT>::updateCachedRenderTarget(
+    const gl::Context *context,
+    const gl::FramebufferAttachment *attachment,
+    RenderTargetT **cachedRenderTarget)
+{
+    RenderTargetT *newRenderTarget = nullptr;
+    if (attachment)
+    {
+        ASSERT(attachment->isAttached());
+        ANGLE_TRY(attachment->getRenderTarget(context, &newRenderTarget));
+    }
+    *cachedRenderTarget = newRenderTarget;
+    return gl::NoError();
+}
+
+template <typename RenderTargetT>
+RenderTargetT *RenderTargetCache<RenderTargetT>::getColorRead(
+    const gl::FramebufferState &state) const
+{
+    ASSERT(mColorRenderTargets[state.getReadIndex()] &&
+           state.getReadIndex() < mColorRenderTargets.size());
+    return mColorRenderTargets[state.getReadIndex()];
+}
+
+}  // namespace rx
+
+#endif  // LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_
--- a/gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.cpp
@@ -20,33 +20,31 @@ TextureImpl::~TextureImpl()
 }
 
 gl::Error TextureImpl::onDestroy(const gl::Context *context)
 {
     return gl::NoError();
 }
 
 gl::Error TextureImpl::copyTexture(const gl::Context *context,
-                                   GLenum target,
-                                   size_t level,
+                                   const gl::ImageIndex &index,
                                    GLenum internalFormat,
                                    GLenum type,
                                    size_t sourceLevel,
                                    bool unpackFlipY,
                                    bool unpackPremultiplyAlpha,
                                    bool unpackUnmultiplyAlpha,
                                    const gl::Texture *source)
 {
     UNREACHABLE();
     return gl::InternalError() << "CHROMIUM_copy_texture exposed but not implemented.";
 }
 
 gl::Error TextureImpl::copySubTexture(const gl::Context *context,
-                                      GLenum target,
-                                      size_t level,
+                                      const gl::ImageIndex &index,
                                       const gl::Offset &destOffset,
                                       size_t sourceLevel,
                                       const gl::Rectangle &sourceArea,
                                       bool unpackFlipY,
                                       bool unpackPremultiplyAlpha,
                                       bool unpackUnmultiplyAlpha,
                                       const gl::Texture *source)
 {
--- a/gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.h
@@ -44,105 +44,97 @@ class TextureImpl : public FramebufferAt
 {
   public:
     TextureImpl(const gl::TextureState &state);
     ~TextureImpl() override;
 
     virtual gl::Error onDestroy(const gl::Context *context);
 
     virtual gl::Error setImage(const gl::Context *context,
-                               GLenum target,
-                               size_t level,
+                               const gl::ImageIndex &index,
                                GLenum internalFormat,
                                const gl::Extents &size,
                                GLenum format,
                                GLenum type,
                                const gl::PixelUnpackState &unpack,
-                               const uint8_t *pixels) = 0;
+                               const uint8_t *pixels)    = 0;
     virtual gl::Error setSubImage(const gl::Context *context,
-                                  GLenum target,
-                                  size_t level,
+                                  const gl::ImageIndex &index,
                                   const gl::Box &area,
                                   GLenum format,
                                   GLenum type,
                                   const gl::PixelUnpackState &unpack,
                                   const uint8_t *pixels) = 0;
 
     virtual gl::Error setCompressedImage(const gl::Context *context,
-                                         GLenum target,
-                                         size_t level,
+                                         const gl::ImageIndex &index,
                                          GLenum internalFormat,
                                          const gl::Extents &size,
                                          const gl::PixelUnpackState &unpack,
                                          size_t imageSize,
-                                         const uint8_t *pixels) = 0;
+                                         const uint8_t *pixels)    = 0;
     virtual gl::Error setCompressedSubImage(const gl::Context *context,
-                                            GLenum target,
-                                            size_t level,
+                                            const gl::ImageIndex &index,
                                             const gl::Box &area,
                                             GLenum format,
                                             const gl::PixelUnpackState &unpack,
                                             size_t imageSize,
                                             const uint8_t *pixels) = 0;
 
     virtual gl::Error copyImage(const gl::Context *context,
-                                GLenum target,
-                                size_t level,
+                                const gl::ImageIndex &index,
                                 const gl::Rectangle &sourceArea,
                                 GLenum internalFormat,
-                                const gl::Framebuffer *source) = 0;
+                                gl::Framebuffer *source)    = 0;
     virtual gl::Error copySubImage(const gl::Context *context,
-                                   GLenum target,
-                                   size_t level,
+                                   const gl::ImageIndex &index,
                                    const gl::Offset &destOffset,
                                    const gl::Rectangle &sourceArea,
-                                   const gl::Framebuffer *source) = 0;
+                                   gl::Framebuffer *source) = 0;
 
     virtual gl::Error copyTexture(const gl::Context *context,
-                                  GLenum target,
-                                  size_t level,
+                                  const gl::ImageIndex &index,
                                   GLenum internalFormat,
                                   GLenum type,
                                   size_t sourceLevel,
                                   bool unpackFlipY,
                                   bool unpackPremultiplyAlpha,
                                   bool unpackUnmultiplyAlpha,
                                   const gl::Texture *source);
     virtual gl::Error copySubTexture(const gl::Context *context,
-                                     GLenum target,
-                                     size_t level,
+                                     const gl::ImageIndex &index,
                                      const gl::Offset &destOffset,
                                      size_t sourceLevel,
                                      const gl::Rectangle &sourceArea,
                                      bool unpackFlipY,
                                      bool unpackPremultiplyAlpha,
                                      bool unpackUnmultiplyAlpha,
                                      const gl::Texture *source);
 
     virtual gl::Error copyCompressedTexture(const gl::Context *context, const gl::Texture *source);
 
     virtual gl::Error setStorage(const gl::Context *context,
-                                 GLenum target,
+                                 gl::TextureType type,
                                  size_t levels,
                                  GLenum internalFormat,
                                  const gl::Extents &size) = 0;
 
     virtual gl::Error setStorageMultisample(const gl::Context *context,
-                                            GLenum target,
+                                            gl::TextureType type,
                                             GLsizei samples,
                                             GLint internalformat,
                                             const gl::Extents &size,
                                             bool fixedSampleLocations) = 0;
 
     virtual gl::Error setEGLImageTarget(const gl::Context *context,
-                                        GLenum target,
+                                        gl::TextureType type,
                                         egl::Image *image) = 0;
 
     virtual gl::Error setImageExternal(const gl::Context *context,
-                                       GLenum target,
+                                       gl::TextureType type,
                                        egl::Stream *stream,
                                        const egl::Stream::GLTextureDescription &desc) = 0;
 
     virtual gl::Error generateMipmap(const gl::Context *context) = 0;
 
     virtual gl::Error setBaseLevel(const gl::Context *context, GLuint baseLevel) = 0;
 
     virtual gl::Error bindTexImage(const gl::Context *context, egl::Surface *surface) = 0;
--- a/gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.h
@@ -16,22 +16,26 @@
 namespace rx
 {
 class ContextImpl;
 
 class VertexArrayImpl : angle::NonCopyable
 {
   public:
     VertexArrayImpl(const gl::VertexArrayState &state) : mState(state) {}
-    virtual void syncState(const gl::Context *context, const gl::VertexArray::DirtyBits &dirtyBits)
+    virtual gl::Error syncState(const gl::Context *context,
+                                const gl::VertexArray::DirtyBits &dirtyBits,
+                                const gl::VertexArray::DirtyAttribBitsArray &attribBits,
+                                const gl::VertexArray::DirtyBindingBitsArray &bindingBits)
     {
+        return gl::NoError();
     }
 
     virtual void destroy(const gl::Context *context) {}
     virtual ~VertexArrayImpl() {}
 
   protected:
     const gl::VertexArrayState &mState;
 };
 
-}
+}  // namespace rx
 
 #endif // LIBANGLE_RENDERER_VERTEXARRAYIMPL_H_
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.cpp
@@ -155,20 +155,21 @@ void BufferD3D::invalidateStaticData(con
     {
         initializeStaticData(context);
     }
 
     mUnmodifiedDataUse = 0;
 }
 
 // Creates static buffers if sufficient used data has been left unmodified
-void BufferD3D::promoteStaticUsage(const gl::Context *context, int dataSize)
+void BufferD3D::promoteStaticUsage(const gl::Context *context, size_t dataSize)
 {
     if (mUsage == D3DBufferUsage::DYNAMIC)
     {
+        // Note: This is not a safe math operation. 'dataSize' can come from the app.
         mUnmodifiedDataUse += dataSize;
 
         if (mUnmodifiedDataUse > 3 * getSize())
         {
             updateD3DBufferUsage(context, gl::BufferUsage::StaticDraw);
         }
     }
 }
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.h
@@ -50,17 +50,17 @@ class BufferD3D : public BufferImpl
     // function.
     StaticVertexBufferInterface *getStaticVertexBuffer(const gl::VertexAttribute &attribute,
                                                        const gl::VertexBinding &binding);
     StaticIndexBufferInterface *getStaticIndexBuffer();
 
     virtual void initializeStaticData(const gl::Context *context);
     virtual void invalidateStaticData(const gl::Context *context);
 
-    void promoteStaticUsage(const gl::Context *context, int dataSize);
+    void promoteStaticUsage(const gl::Context *context, size_t dataSize);
 
     gl::Error getIndexRange(const gl::Context *context,
                             GLenum type,
                             size_t offset,
                             size_t count,
                             bool primitiveRestartEnabled,
                             gl::IndexRange *outRange) override;
 
@@ -75,15 +75,15 @@ class BufferD3D : public BufferImpl
     BufferFactoryD3D *mFactory;
     unsigned int mSerial;
     static unsigned int mNextSerial;
 
     std::vector<std::unique_ptr<StaticVertexBufferInterface>> mStaticVertexBuffers;
     StaticIndexBufferInterface *mStaticIndexBuffer;
     unsigned int mStaticBufferCacheTotalSize;
     unsigned int mStaticVertexBufferOutOfDate;
-    unsigned int mUnmodifiedDataUse;
+    size_t mUnmodifiedDataUse;
     D3DBufferUsage mUsage;
 };
 
 }
 
 #endif // LIBANGLE_RENDERER_D3D_BUFFERD3D_H_
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
@@ -455,18 +455,18 @@ void DynamicHLSL::generateShaderLinkHLSL
                                          const VaryingPacking &varyingPacking,
                                          const BuiltinVaryingsD3D &builtinsD3D,
                                          std::string *pixelHLSL,
                                          std::string *vertexHLSL) const
 {
     ASSERT(pixelHLSL->empty() && vertexHLSL->empty());
 
     const auto &data                   = context->getContextState();
-    gl::Shader *vertexShaderGL         = programData.getAttachedVertexShader();
-    gl::Shader *fragmentShaderGL       = programData.getAttachedFragmentShader();
+    gl::Shader *vertexShaderGL         = programData.getAttachedShader(ShaderType::Vertex);
+    gl::Shader *fragmentShaderGL       = programData.getAttachedShader(ShaderType::Fragment);
     const ShaderD3D *fragmentShader    = GetImplAs<ShaderD3D>(fragmentShaderGL);
     const int shaderModel              = mRenderer->getMajorShaderModel();
 
     // usesViewScale() isn't supported in the D3D9 renderer
     ASSERT(shaderModel >= 4 || !programMetadata.usesViewScale());
 
     bool useInstancedPointSpriteEmulation =
         programMetadata.usesPointSize() &&
@@ -486,17 +486,17 @@ void DynamicHLSL::generateShaderLinkHLSL
                      << static_cast<int>(data.getCaps().minAliasedPointSize) << ".0f;\n"
                      << "static float maxPointSize = "
                      << static_cast<int>(data.getCaps().maxAliasedPointSize) << ".0f;\n";
     }
 
     // Add stub string to be replaced when shader is dynamically defined by its layout
     vertexStream << "\n" << std::string(VERTEX_ATTRIBUTE_STUB_STRING) << "\n";
 
-    const auto &vertexBuiltins = builtinsD3D[gl::SHADER_VERTEX];
+    const auto &vertexBuiltins = builtinsD3D[gl::ShaderType::Vertex];
 
     // Write the HLSL input/output declarations
     vertexStream << "struct VS_OUTPUT\n";
     generateVaryingLinkHLSL(varyingPacking, vertexBuiltins, builtinsD3D.usesPointSize(),
                             vertexStream);
     vertexStream << "\n"
                  << "VS_OUTPUT main(VS_INPUT input)\n"
                  << "{\n"
@@ -652,17 +652,17 @@ void DynamicHLSL::generateShaderLinkHLSL
         vertexStream << "\n"
                      << "    output.gl_PointCoord = float2(0.5, 0.5);\n";
     }
 
     vertexStream << "\n"
                  << "    return output;\n"
                  << "}\n";
 
-    const auto &pixelBuiltins = builtinsD3D[gl::SHADER_FRAGMENT];
+    const auto &pixelBuiltins = builtinsD3D[gl::ShaderType::Fragment];
 
     std::ostringstream pixelStream;
     pixelStream << fragmentShaderGL->getTranslatedSource(context);
     pixelStream << "struct PS_INPUT\n";
     generateVaryingLinkHLSL(varyingPacking, pixelBuiltins, builtinsD3D.usesPointSize(),
                             pixelStream);
     pixelStream << "\n";
 
@@ -788,18 +788,18 @@ void DynamicHLSL::generateShaderLinkHLSL
 
     for (const PackedVaryingRegister &registerInfo : varyingPacking.getRegisterList())
     {
         const auto &packedVarying = *registerInfo.packedVarying;
         const auto &varying = *packedVarying.varying;
         ASSERT(!varying.isBuiltIn() && !varying.isStruct());
 
         // Don't reference VS-only transform feedback varyings in the PS. Note that we're relying on
-        // that the staticUse flag is set according to usage in the fragment shader.
-        if (packedVarying.vertexOnly || !varying.staticUse)
+        // that the active flag is set according to usage in the fragment shader.
+        if (packedVarying.vertexOnly || !varying.active)
             continue;
 
         pixelStream << "    ";
 
         if (packedVarying.isStructField())
         {
             pixelStream << DecorateVariable(packedVarying.parentStructName) << ".";
         }
@@ -846,17 +846,17 @@ void DynamicHLSL::generateShaderLinkHLSL
 
     *vertexHLSL = vertexStream.str();
     *pixelHLSL  = pixelStream.str();
 }
 
 std::string DynamicHLSL::generateComputeShaderLinkHLSL(const gl::Context *context,
                                                        const gl::ProgramState &programData) const
 {
-    gl::Shader *computeShaderGL = programData.getAttachedComputeShader();
+    gl::Shader *computeShaderGL = programData.getAttachedShader(ShaderType::Compute);
     std::stringstream computeStream;
     std::string translatedSource = computeShaderGL->getTranslatedSource(context);
     computeStream << translatedSource;
 
     bool usesWorkGroupID = translatedSource.find("GL_USES_WORK_GROUP_ID") != std::string::npos;
     bool usesLocalInvocationID =
         translatedSource.find("GL_USES_LOCAL_INVOCATION_ID") != std::string::npos;
     bool usesGlobalInvocationID =
@@ -926,24 +926,24 @@ std::string DynamicHLSL::generateGeometr
                                                         const BuiltinVaryingsD3D &builtinsD3D,
                                                         const bool hasANGLEMultiviewEnabled,
                                                         const bool selectViewInVS) const
 {
     ASSERT(mRenderer->getMajorShaderModel() >= 4);
 
     std::ostringstream preambleStream;
 
-    const auto &vertexBuiltins = builtinsD3D[gl::SHADER_VERTEX];
+    const auto &vertexBuiltins = builtinsD3D[gl::ShaderType::Vertex];
 
     preambleStream << "struct GS_INPUT\n";
     generateVaryingLinkHLSL(varyingPacking, vertexBuiltins, builtinsD3D.usesPointSize(),
                             preambleStream);
     preambleStream << "\n"
                    << "struct GS_OUTPUT\n";
-    generateVaryingLinkHLSL(varyingPacking, builtinsD3D[gl::SHADER_GEOMETRY],
+    generateVaryingLinkHLSL(varyingPacking, builtinsD3D[gl::ShaderType::Geometry],
                             builtinsD3D.usesPointSize(), preambleStream);
     preambleStream
         << "\n"
         << "void copyVertex(inout GS_OUTPUT output, GS_INPUT input, GS_INPUT flatinput)\n"
         << "{\n"
         << "    output.gl_Position = input.gl_Position;\n";
 
     if (vertexBuiltins.glPointSize.enabled)
@@ -951,18 +951,18 @@ std::string DynamicHLSL::generateGeometr
         preambleStream << "    output.gl_PointSize = input.gl_PointSize;\n";
     }
 
     if (hasANGLEMultiviewEnabled)
     {
         preambleStream << "    output.gl_ViewID_OVR = input.gl_ViewID_OVR;\n";
         if (selectViewInVS)
         {
-            ASSERT(builtinsD3D[gl::SHADER_GEOMETRY].glViewportIndex.enabled &&
-                   builtinsD3D[gl::SHADER_GEOMETRY].glLayer.enabled);
+            ASSERT(builtinsD3D[gl::ShaderType::Geometry].glViewportIndex.enabled &&
+                   builtinsD3D[gl::ShaderType::Geometry].glLayer.enabled);
 
             // If the view is already selected in the VS, then we just pass the gl_ViewportIndex and
             // gl_Layer to the output.
             preambleStream << "    output.gl_ViewportIndex = input.gl_ViewportIndex;\n"
                            << "    output.gl_Layer = input.gl_Layer;\n";
         }
     }
 
@@ -984,18 +984,18 @@ std::string DynamicHLSL::generateGeometr
     // Only write the dx_Position if we aren't using point sprites
     preambleStream << "#ifndef ANGLE_POINT_SPRITE_SHADER\n"
                    << "    output.dx_Position = input.dx_Position;\n"
                    << "#endif  // ANGLE_POINT_SPRITE_SHADER\n"
                    << "}\n";
 
     if (hasANGLEMultiviewEnabled && !selectViewInVS)
     {
-        ASSERT(builtinsD3D[gl::SHADER_GEOMETRY].glViewportIndex.enabled &&
-               builtinsD3D[gl::SHADER_GEOMETRY].glLayer.enabled);
+        ASSERT(builtinsD3D[gl::ShaderType::Geometry].glViewportIndex.enabled &&
+               builtinsD3D[gl::ShaderType::Geometry].glLayer.enabled);
 
         // According to the HLSL reference, using SV_RenderTargetArrayIndex is only valid if the
         // render target is an array resource. Because of this we do not write to gl_Layer if we are
         // taking the side-by-side code path. We still select the viewport index in the layered code
         // path as that is always valid. See:
         // https://msdn.microsoft.com/en-us/library/windows/desktop/bb509647(v=vs.85).aspx
         preambleStream << "\n"
                        << "void selectView(inout GS_OUTPUT output, GS_INPUT input)\n"
@@ -1281,17 +1281,17 @@ void DynamicHLSL::getPixelShaderOutputKe
             }
             const sh::ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index];
             const std::string &variableName          = "out_" + outputVariable.name;
 
             // Fragment outputs can't be arrays of arrays. ESSL 3.10 section 4.3.6.
             const std::string &elementString =
                 (outputVariable.isArray() ? Str(outputLocation.arrayIndex) : "");
 
-            ASSERT(outputVariable.staticUse);
+            ASSERT(outputVariable.active);
 
             PixelShaderOutputVariable outputKeyVariable;
             outputKeyVariable.type        = outputVariable.type;
             outputKeyVariable.name        = variableName + elementString;
             outputKeyVariable.source =
                 variableName +
                 (outputVariable.isArray() ? ArrayString(outputLocation.arrayIndex) : "");
             outputKeyVariable.outputIndex = outputLocationIndex;
@@ -1324,42 +1324,42 @@ void BuiltinVarying::enable(const std::s
     semantic = semanticVal;
     index    = indexVal;
 }
 
 // BuiltinVaryingsD3D Implementation.
 BuiltinVaryingsD3D::BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata,
                                        const VaryingPacking &packing)
 {
-    updateBuiltins(gl::SHADER_VERTEX, metadata, packing);
-    updateBuiltins(gl::SHADER_FRAGMENT, metadata, packing);
+    updateBuiltins(gl::ShaderType::Vertex, metadata, packing);
+    updateBuiltins(gl::ShaderType::Fragment, metadata, packing);
     if (metadata.getRendererMajorShaderModel() >= 4)
     {
-        updateBuiltins(gl::SHADER_GEOMETRY, metadata, packing);
+        updateBuiltins(gl::ShaderType::Geometry, metadata, packing);
     }
 }
 
 BuiltinVaryingsD3D::~BuiltinVaryingsD3D() = default;
 
 void BuiltinVaryingsD3D::updateBuiltins(gl::ShaderType shaderType,
                                         const ProgramD3DMetadata &metadata,
                                         const VaryingPacking &packing)
 {
     const std::string &userSemantic = GetVaryingSemantic(metadata.getRendererMajorShaderModel(),
                                                          metadata.usesSystemValuePointSize());
 
     unsigned int reservedSemanticIndex = packing.getMaxSemanticIndex();
 
-    BuiltinInfo *builtins = &mBuiltinInfo[shaderType];
+    BuiltinInfo *builtins = &mBuiltinInfo[static_cast<size_t>(shaderType)];
 
     if (metadata.getRendererMajorShaderModel() >= 4)
     {
         builtins->dxPosition.enableSystem("SV_Position");
     }
-    else if (shaderType == gl::SHADER_FRAGMENT)
+    else if (shaderType == gl::ShaderType::Fragment)
     {
         builtins->dxPosition.enableSystem("VPOS");
     }
     else
     {
         builtins->dxPosition.enableSystem("POSITION");
     }
 
@@ -1368,60 +1368,60 @@ void BuiltinVaryingsD3D::updateBuiltins(
         builtins->glPosition.enable(userSemantic, reservedSemanticIndex++);
     }
 
     if (metadata.usesFragCoord())
     {
         builtins->glFragCoord.enable(userSemantic, reservedSemanticIndex++);
     }
 
-    if (shaderType == gl::SHADER_VERTEX ? metadata.addsPointCoordToVertexShader()
-                                        : metadata.usesPointCoord())
+    if (shaderType == gl::ShaderType::Vertex ? metadata.addsPointCoordToVertexShader()
+                                             : metadata.usesPointCoord())
     {
         // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord)
         // In D3D11 we manually compute gl_PointCoord in the GS.
         if (metadata.getRendererMajorShaderModel() >= 4)
         {
             builtins->glPointCoord.enable(userSemantic, reservedSemanticIndex++);
         }
         else
         {
             builtins->glPointCoord.enable("TEXCOORD", 0);
         }
     }
 
-    if (shaderType == gl::SHADER_VERTEX && metadata.hasANGLEMultiviewEnabled())
+    if (shaderType == gl::ShaderType::Vertex && metadata.hasANGLEMultiviewEnabled())
     {
         builtins->glViewIDOVR.enable(userSemantic, reservedSemanticIndex++);
         if (metadata.canSelectViewInVertexShader())
         {
             builtins->glViewportIndex.enableSystem("SV_ViewportArrayIndex");
             builtins->glLayer.enableSystem("SV_RenderTargetArrayIndex");
         }
     }
 
-    if (shaderType == gl::SHADER_FRAGMENT && metadata.hasANGLEMultiviewEnabled())
+    if (shaderType == gl::ShaderType::Fragment && metadata.hasANGLEMultiviewEnabled())
     {
         builtins->glViewIDOVR.enable(userSemantic, reservedSemanticIndex++);
     }
 
-    if (shaderType == gl::SHADER_GEOMETRY && metadata.hasANGLEMultiviewEnabled())
+    if (shaderType == gl::ShaderType::Geometry && metadata.hasANGLEMultiviewEnabled())
     {
         // Although it is possible to retrieve gl_ViewID_OVR from the value of
         // SV_ViewportArrayIndex or SV_RenderTargetArrayIndex based on the multi-view state in the
         // driver constant buffer, it is easier and cleaner to pass it as a varying.
         builtins->glViewIDOVR.enable(userSemantic, reservedSemanticIndex++);
 
         // gl_Layer and gl_ViewportIndex are necessary so that we can write to either based on the
         // multiview state in the driver constant buffer.
         builtins->glViewportIndex.enableSystem("SV_ViewportArrayIndex");
         builtins->glLayer.enableSystem("SV_RenderTargetArrayIndex");
     }
 
     // Special case: do not include PSIZE semantic in HLSL 3 pixel shaders
     if (metadata.usesSystemValuePointSize() &&
-        (shaderType != gl::SHADER_FRAGMENT || metadata.getRendererMajorShaderModel() >= 4))
+        (shaderType != gl::ShaderType::Fragment || metadata.getRendererMajorShaderModel() >= 4))
     {
         builtins->glPointSize.enableSystem("PSIZE");
     }
 }
 
 }  // namespace rx
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.h
@@ -93,30 +93,36 @@ inline std::string GetVaryingSemantic(in
 }
 
 class BuiltinVaryingsD3D
 {
   public:
     BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata, const gl::VaryingPacking &packing);
     ~BuiltinVaryingsD3D();
 
-    bool usesPointSize() const { return mBuiltinInfo[gl::SHADER_VERTEX].glPointSize.enabled; }
+    bool usesPointSize() const
+    {
+        return mBuiltinInfo[static_cast<size_t>(gl::ShaderType::Vertex)].glPointSize.enabled;
+    }
 
     const BuiltinInfo &operator[](gl::ShaderType shaderType) const
     {
-        return mBuiltinInfo[shaderType];
+        return mBuiltinInfo[static_cast<size_t>(shaderType)];
     }
-    BuiltinInfo &operator[](gl::ShaderType shaderType) { return mBuiltinInfo[shaderType]; }
+    BuiltinInfo &operator[](gl::ShaderType shaderType)
+    {
+        return mBuiltinInfo[static_cast<size_t>(shaderType)];
+    }
 
   private:
     void updateBuiltins(gl::ShaderType shaderType,
                         const ProgramD3DMetadata &metadata,
                         const gl::VaryingPacking &packing);
 
-    std::array<BuiltinInfo, gl::SHADER_TYPE_MAX> mBuiltinInfo;
+    std::array<BuiltinInfo, static_cast<size_t>(gl::ShaderType::EnumCount)> mBuiltinInfo;
 };
 
 class DynamicHLSL : angle::NonCopyable
 {
   public:
     explicit DynamicHLSL(RendererD3D *const renderer);
 
     std::string generateVertexShaderForInputLayout(
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.cpp
@@ -75,13 +75,16 @@ gl::Error EGLImageD3D::copyToLocalRender
 {
     ASSERT(mState.source.get() != nullptr);
     ASSERT(mRenderTarget == nullptr);
 
     RenderTargetD3D *curRenderTarget = nullptr;
     ANGLE_TRY(getRenderTarget(context, &curRenderTarget));
 
     // This only currently applies do D3D11, where it invalidates FBOs with this Image attached.
-    curRenderTarget->signalDirty(context);
+    for (egl::ImageSibling *target : mState.targets)
+    {
+        target->getSubject()->onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
+    }
 
     return mRenderer->createRenderTargetCopy(curRenderTarget, &mRenderTarget);
 }
 }  // namespace rx
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
@@ -252,27 +252,27 @@ gl::Error FramebufferD3D::readPixels(con
     if (!ClipRectangle(origArea, fbRect, &area))
     {
         // nothing to read
         return gl::NoError();
     }
 
     const gl::PixelPackState &packState = context->getGLState().getPackState();
 
-    const gl::InternalFormat &packFormat = gl::GetPackFormatInfo(format, type);
+    const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(format, type);
 
     GLuint outputPitch = 0;
-    ANGLE_TRY_RESULT(packFormat.computeRowPitch(origArea.width, packState.alignment,
-                                                packState.rowLength),
+    ANGLE_TRY_RESULT(sizedFormatInfo.computeRowPitch(type, origArea.width, packState.alignment,
+                                                     packState.rowLength),
                      outputPitch);
     GLuint outputSkipBytes = 0;
-    ANGLE_TRY_RESULT(packFormat.computeSkipBytes(outputPitch, 0, packState, false),
+    ANGLE_TRY_RESULT(sizedFormatInfo.computeSkipBytes(type, outputPitch, 0, packState, false),
                      outputSkipBytes);
     outputSkipBytes +=
-        (area.x - origArea.x) * packFormat.pixelBytes + (area.y - origArea.y) * outputPitch;
+        (area.x - origArea.x) * sizedFormatInfo.pixelBytes + (area.y - origArea.y) * outputPitch;
 
     return readPixelsImpl(context, area, format, type, outputPitch, packState,
                           reinterpret_cast<uint8_t *>(pixels) + outputSkipBytes);
 }
 
 gl::Error FramebufferD3D::blit(const gl::Context *context,
                                const gl::Rectangle &sourceArea,
                                const gl::Rectangle &destArea,
@@ -314,33 +314,35 @@ bool FramebufferD3D::checkStatus(const g
     if (!mState.attachmentsHaveSameDimensions())
     {
         return false;
     }
 
     return true;
 }
 
-void FramebufferD3D::syncState(const gl::Context *context,
-                               const gl::Framebuffer::DirtyBits &dirtyBits)
+gl::Error FramebufferD3D::syncState(const gl::Context *context,
+                                    const gl::Framebuffer::DirtyBits &dirtyBits)
 {
     if (!mColorAttachmentsForRender.valid())
     {
-        return;
+        return gl::NoError();
     }
 
     for (auto dirtyBit : dirtyBits)
     {
         if ((dirtyBit >= gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 &&
              dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX) ||
             dirtyBit == gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS)
         {
             mColorAttachmentsForRender.reset();
         }
     }
+
+    return gl::NoError();
 }
 
 const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const gl::Context *context)
 {
     gl::DrawBufferMask activeProgramOutputs =
         context->getContextState().getState().getProgram()->getActiveOutputVariables();
 
     if (mColorAttachmentsForRender.valid() && mCurrentActiveProgramOutputs == activeProgramOutputs)
@@ -395,17 +397,18 @@ const gl::AttachmentList &FramebufferD3D
             // it to be attached to a new binding point.
             if (mDummyAttachment.isAttached())
             {
                 mDummyAttachment.detach(context);
             }
 
             gl::Texture *dummyTex = nullptr;
             // TODO(Jamie): Handle error if dummy texture can't be created.
-            ANGLE_SWALLOW_ERR(mRenderer->getIncompleteTexture(context, GL_TEXTURE_2D, &dummyTex));
+            ANGLE_SWALLOW_ERR(
+                mRenderer->getIncompleteTexture(context, gl::TextureType::_2D, &dummyTex));
             if (dummyTex)
             {
 
                 gl::ImageIndex index = gl::ImageIndex::Make2D(0);
                 mDummyAttachment     = gl::FramebufferAttachment(
                     context, GL_TEXTURE, GL_COLOR_ATTACHMENT0_EXT + activeProgramLocation, index,
                     dummyTex);
                 colorAttachmentsForRender.push_back(&mDummyAttachment);
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.h
@@ -92,18 +92,18 @@ class FramebufferD3D : public Framebuffe
     gl::Error blit(const gl::Context *context,
                    const gl::Rectangle &sourceArea,
                    const gl::Rectangle &destArea,
                    GLbitfield mask,
                    GLenum filter) override;
 
     bool checkStatus(const gl::Context *context) const override;
 
-    void syncState(const gl::Context *context,
-                   const gl::Framebuffer::DirtyBits &dirtyBits) override;
+    gl::Error syncState(const gl::Context *context,
+                        const gl::Framebuffer::DirtyBits &dirtyBits) override;
 
     const gl::AttachmentList &getColorAttachmentsForRender(const gl::Context *context);
 
     void destroy(const gl::Context *context) override;
 
   private:
     virtual gl::Error clearImpl(const gl::Context *context, const ClearParameters &clearParams) = 0;
 
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.cpp
@@ -19,17 +19,17 @@ namespace rx
 {
 
 ImageD3D::ImageD3D()
     : mWidth(0),
       mHeight(0),
       mDepth(0),
       mInternalFormat(GL_NONE),
       mRenderable(false),
-      mTarget(GL_NONE),
+      mType(gl::TextureType::InvalidEnum),
       mDirty(false)
 {
 }
 
 gl::Error ImageD3D::setManagedSurface2D(const gl::Context *context,
                                         TextureStorage *storage,
                                         int level)
 {
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.h
@@ -9,16 +9,17 @@
 // surfaces or resources.
 
 #ifndef LIBANGLE_RENDERER_D3D_IMAGED3D_H_
 #define LIBANGLE_RENDERER_D3D_IMAGED3D_H_
 
 #include "common/debug.h"
 
 #include "libANGLE/Error.h"
+#include "libANGLE/PackedGLEnums.h"
 
 namespace gl
 {
 class Context;
 class Framebuffer;
 struct ImageIndex;
 struct Box;
 struct Extents;
@@ -38,24 +39,27 @@ class ImageD3D : angle::NonCopyable
   public:
     ImageD3D();
     virtual ~ImageD3D() {};
 
     GLsizei getWidth() const { return mWidth; }
     GLsizei getHeight() const { return mHeight; }
     GLsizei getDepth() const { return mDepth; }
     GLenum getInternalFormat() const { return mInternalFormat; }
-    GLenum getTarget() const { return mTarget; }
+    gl::TextureType getType() const { return mType; }
     bool isRenderableFormat() const { return mRenderable; }
 
     void markDirty() { mDirty = true; }
     void markClean() { mDirty = false; }
     virtual bool isDirty() const = 0;
 
-    virtual bool redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease) = 0;
+    virtual bool redefine(gl::TextureType type,
+                          GLenum internalformat,
+                          const gl::Extents &size,
+                          bool forceRelease) = 0;
 
     virtual gl::Error loadData(const gl::Context *context,
                                const gl::Box &area,
                                const gl::PixelUnpackState &unpack,
                                GLenum type,
                                const void *input,
                                bool applySkipImages) = 0;
     virtual gl::Error loadCompressedData(const gl::Context *context,
@@ -90,16 +94,16 @@ class ImageD3D : angle::NonCopyable
                                           const gl::Framebuffer *source) = 0;
 
   protected:
     GLsizei mWidth;
     GLsizei mHeight;
     GLsizei mDepth;
     GLenum mInternalFormat;
     bool mRenderable;
-    GLenum mTarget;
+    gl::TextureType mType;
 
     bool mDirty;
 };
 
 }
 
 #endif // LIBANGLE_RENDERER_D3D_IMAGED3D_H_
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.cpp
@@ -294,27 +294,38 @@ gl::Error IndexDataManager::getStreaming
         ANGLE_TRY(newBuffer->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, destinationIndexType));
         streamingBuffer = std::move(newBuffer);
     }
 
     *outBuffer = streamingBuffer.get();
     return gl::NoError();
 }
 
-GLenum GetIndexTranslationDestType(GLenum srcType,
-                                   const gl::HasIndexRange &lazyIndexRange,
-                                   bool usePrimitiveRestartWorkaround)
+gl::Error GetIndexTranslationDestType(const gl::Context *context,
+                                      const gl::DrawCallParams &drawCallParams,
+                                      bool usePrimitiveRestartWorkaround,
+                                      GLenum *destTypeOut)
 {
     // Avoid D3D11's primitive restart index value
     // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx
     if (usePrimitiveRestartWorkaround)
     {
-        const gl::IndexRange &indexRange = lazyIndexRange.getIndexRange().value();
-        if (indexRange.end == gl::GetPrimitiveRestartIndex(srcType))
+        // Conservatively assume we need to translate the indices for draw indirect.
+        if (drawCallParams.isDrawIndirect())
         {
-            return GL_UNSIGNED_INT;
+            *destTypeOut = GL_UNSIGNED_INT;
+            return gl::NoError();
+        }
+
+        ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
+        const gl::IndexRange &indexRange = drawCallParams.getIndexRange();
+        if (indexRange.end == gl::GetPrimitiveRestartIndex(drawCallParams.type()))
+        {
+            *destTypeOut = GL_UNSIGNED_INT;
+            return gl::NoError();
         }
     }
 
-    return (srcType == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
+    *destTypeOut = (drawCallParams.type() == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
+    return gl::NoError();
 }
 
 }  // namespace rx
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.h
@@ -89,17 +89,18 @@ class IndexDataManager : angle::NonCopya
 
     using StreamingBuffer = std::unique_ptr<StreamingIndexBufferInterface>;
 
     BufferFactoryD3D *const mFactory;
     std::unique_ptr<StreamingIndexBufferInterface> mStreamingBufferShort;
     std::unique_ptr<StreamingIndexBufferInterface> mStreamingBufferInt;
 };
 
-GLenum GetIndexTranslationDestType(GLenum srcType,
-                                   const gl::HasIndexRange &lazyIndexRange,
-                                   bool usePrimitiveRestartWorkaround);
+gl::Error GetIndexTranslationDestType(const gl::Context *context,
+                                      const gl::DrawCallParams &drawCallParams,
+                                      bool usePrimitiveRestartWorkaround,
+                                      GLenum *destTypeOut);
 
 bool IsOffsetAligned(GLenum elementType, unsigned int offset);
 
 }  // namespace rx
 
 #endif  // LIBANGLE_INDEXDATAMANAGER_H_
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -216,30 +216,30 @@ class UniformBlockInfo final : angle::No
     std::map<std::string, size_t> mBlockSizes;
     sh::BlockLayoutMap mBlockLayout;
 };
 
 void UniformBlockInfo::getShaderBlockInfo(const gl::Context *context, gl::Shader *shader)
 {
     for (const sh::InterfaceBlock &interfaceBlock : shader->getUniformBlocks(context))
     {
-        if (!interfaceBlock.staticUse && interfaceBlock.layout == sh::BLOCKLAYOUT_PACKED)
+        if (!interfaceBlock.active && interfaceBlock.layout == sh::BLOCKLAYOUT_PACKED)
             continue;
 
         if (mBlockSizes.count(interfaceBlock.name) > 0)
             continue;
 
         size_t dataSize                  = getBlockInfo(interfaceBlock);
         mBlockSizes[interfaceBlock.name] = dataSize;
     }
 }
 
 size_t UniformBlockInfo::getBlockInfo(const sh::InterfaceBlock &interfaceBlock)
 {
-    ASSERT(interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED);
+    ASSERT(interfaceBlock.active || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED);
 
     // define member uniforms
     sh::Std140BlockEncoder std140Encoder;
     sh::HLSLBlockEncoder hlslEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED, false);
     sh::BlockLayoutEncoder *encoder = nullptr;
 
     if (interfaceBlock.layout == sh::BLOCKLAYOUT_STD140)
     {
@@ -589,17 +589,18 @@ ProgramD3D::PixelExecutable::PixelExecut
 {
 }
 
 ProgramD3D::PixelExecutable::~PixelExecutable()
 {
     SafeDelete(mShaderExecutable);
 }
 
-ProgramD3D::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(GL_TEXTURE_2D)
+ProgramD3D::Sampler::Sampler()
+    : active(false), logicalTextureUnit(0), textureType(gl::TextureType::_2D)
 {
 }
 
 ProgramD3D::Image::Image() : active(false), logicalImageUnit(0)
 {
 }
 
 unsigned int ProgramD3D::mCurrentSerial = 1;
@@ -616,20 +617,17 @@ ProgramD3D::ProgramD3D(const gl::Program
       mFragmentUniformStorage(nullptr),
       mComputeUniformStorage(nullptr),
       mUsedVertexSamplerRange(0),
       mUsedPixelSamplerRange(0),
       mUsedComputeSamplerRange(0),
       mDirtySamplerMapping(true),
       mUsedComputeImageRange(0),
       mUsedComputeReadonlyImageRange(0),
-      mSerial(issueSerial()),
-      mVertexUniformsDirty(true),
-      mFragmentUniformsDirty(true),
-      mComputeUniformsDirty(true)
+      mSerial(issueSerial())
 {
     mDynamicHLSL = new DynamicHLSL(renderer);
 }
 
 ProgramD3D::~ProgramD3D()
 {
     reset();
     SafeDelete(mDynamicHLSL);
@@ -666,31 +664,31 @@ bool ProgramD3D::usesInstancedPointSprit
 GLint ProgramD3D::getSamplerMapping(gl::ShaderType type,
                                     unsigned int samplerIndex,
                                     const gl::Caps &caps) const
 {
     GLint logicalTextureUnit = -1;
 
     switch (type)
     {
-        case gl::SHADER_FRAGMENT:
+        case gl::ShaderType::Fragment:
             ASSERT(samplerIndex < caps.maxTextureImageUnits);
             if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active)
             {
                 logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit;
             }
             break;
-        case gl::SHADER_VERTEX:
+        case gl::ShaderType::Vertex:
             ASSERT(samplerIndex < caps.maxVertexTextureImageUnits);
             if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active)
             {
                 logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
             }
             break;
-        case gl::SHADER_COMPUTE:
+        case gl::ShaderType::Compute:
             ASSERT(samplerIndex < caps.maxComputeTextureImageUnits);
             if (samplerIndex < mSamplersCS.size() && mSamplersCS[samplerIndex].active)
             {
                 logicalTextureUnit = mSamplersCS[samplerIndex].logicalTextureUnit;
             }
             break;
         default:
             UNREACHABLE();
@@ -702,48 +700,49 @@ GLint ProgramD3D::getSamplerMapping(gl::
         return logicalTextureUnit;
     }
 
     return -1;
 }
 
 // Returns the texture type for a given Direct3D 9 sampler type and
 // index (0-15 for the pixel shader and 0-3 for the vertex shader).
-GLenum ProgramD3D::getSamplerTextureType(gl::ShaderType type, unsigned int samplerIndex) const
+gl::TextureType ProgramD3D::getSamplerTextureType(gl::ShaderType type,
+                                                  unsigned int samplerIndex) const
 {
     switch (type)
     {
-        case gl::SHADER_FRAGMENT:
+        case gl::ShaderType::Fragment:
             ASSERT(samplerIndex < mSamplersPS.size());
             ASSERT(mSamplersPS[samplerIndex].active);
             return mSamplersPS[samplerIndex].textureType;
-        case gl::SHADER_VERTEX:
+        case gl::ShaderType::Vertex:
             ASSERT(samplerIndex < mSamplersVS.size());
             ASSERT(mSamplersVS[samplerIndex].active);
             return mSamplersVS[samplerIndex].textureType;
-        case gl::SHADER_COMPUTE:
+        case gl::ShaderType::Compute:
             ASSERT(samplerIndex < mSamplersCS.size());
             ASSERT(mSamplersCS[samplerIndex].active);
             return mSamplersCS[samplerIndex].textureType;
         default:
             UNREACHABLE();
+            return gl::TextureType::InvalidEnum;
     }
 
-    return GL_TEXTURE_2D;
 }
 
 GLuint ProgramD3D::getUsedSamplerRange(gl::ShaderType type) const
 {
     switch (type)
     {
-        case gl::SHADER_FRAGMENT:
+        case gl::ShaderType::Fragment:
             return mUsedPixelSamplerRange;
-        case gl::SHADER_VERTEX:
+        case gl::ShaderType::Vertex:
             return mUsedVertexSamplerRange;
-        case gl::SHADER_COMPUTE:
+        case gl::ShaderType::Compute:
             return mUsedComputeSamplerRange;
         default:
             UNREACHABLE();
             return 0u;
     }
 }
 
 ProgramD3D::SamplerMapping ProgramD3D::updateSamplerMapping()
@@ -819,17 +818,17 @@ GLint ProgramD3D::getImageMapping(gl::Sh
                                   unsigned int imageIndex,
                                   bool readonly,
                                   const gl::Caps &caps) const
 {
     GLint logicalImageUnit = -1;
     ASSERT(imageIndex < caps.maxImageUnits);
     switch (type)
     {
-        case gl::SHADER_COMPUTE:
+        case gl::ShaderType::Compute:
             if (readonly && imageIndex < mReadonlyImagesCS.size() &&
                 mReadonlyImagesCS[imageIndex].active)
             {
                 logicalImageUnit = mReadonlyImagesCS[imageIndex].logicalImageUnit;
             }
             else if (imageIndex < mImagesCS.size() && mImagesCS[imageIndex].active)
             {
                 logicalImageUnit = mImagesCS[imageIndex].logicalImageUnit;
@@ -847,17 +846,17 @@ GLint ProgramD3D::getImageMapping(gl::Sh
 
     return -1;
 }
 
 GLuint ProgramD3D::getUsedImageRange(gl::ShaderType type, bool readonly) const
 {
     switch (type)
     {
-        case gl::SHADER_COMPUTE:
+        case gl::ShaderType::Compute:
             return readonly ? mUsedComputeReadonlyImageRange : mUsedComputeImageRange;
         // TODO(xinghua.cao@intel.com): add image range of vertex shader and pixel shader.
         default:
             UNREACHABLE();
             return 0u;
     }
 }
 
@@ -893,36 +892,36 @@ gl::LinkResult ProgramD3D::load(const gl
     }
 
     const unsigned int psSamplerCount = stream->readInt<unsigned int>();
     for (unsigned int i = 0; i < psSamplerCount; ++i)
     {
         Sampler sampler;
         stream->readBool(&sampler.active);
         stream->readInt(&sampler.logicalTextureUnit);
-        stream->readInt(&sampler.textureType);
+        stream->readEnum(&sampler.textureType);
         mSamplersPS.push_back(sampler);
     }
     const unsigned int vsSamplerCount = stream->readInt<unsigned int>();
     for (unsigned int i = 0; i < vsSamplerCount; ++i)
     {
         Sampler sampler;
         stream->readBool(&sampler.active);
         stream->readInt(&sampler.logicalTextureUnit);
-        stream->readInt(&sampler.textureType);
+        stream->readEnum(&sampler.textureType);
         mSamplersVS.push_back(sampler);
     }
 
     const unsigned int csSamplerCount = stream->readInt<unsigned int>();
     for (unsigned int i = 0; i < csSamplerCount; ++i)
     {
         Sampler sampler;
         stream->readBool(&sampler.active);
         stream->readInt(&sampler.logicalTextureUnit);
-        stream->readInt(&sampler.textureType);
+        stream->readEnum(&sampler.textureType);
         mSamplersCS.push_back(sampler);
     }
 
     const unsigned int csImageCount = stream->readInt<unsigned int>();
     for (unsigned int i = 0; i < csImageCount; ++i)
     {
         Image image;
         stream->readBool(&image.active);
@@ -1042,18 +1041,18 @@ gl::LinkResult ProgramD3D::load(const gl
         }
 
         unsigned int vertexShaderSize             = stream->readInt<unsigned int>();
         const unsigned char *vertexShaderFunction = binary + stream->offset();
 
         ShaderExecutableD3D *shaderExecutable = nullptr;
 
         ANGLE_TRY(mRenderer->loadExecutable(vertexShaderFunction, vertexShaderSize,
-                                            gl::SHADER_VERTEX, mStreamOutVaryings, separateAttribs,
-                                            &shaderExecutable));
+                                            gl::ShaderType::Vertex, mStreamOutVaryings,
+                                            separateAttribs, &shaderExecutable));
 
         if (!shaderExecutable)
         {
             infoLog << "Could not create vertex shader.";
             return false;
         }
 
         // generated converted input layout
@@ -1077,17 +1076,17 @@ gl::LinkResult ProgramD3D::load(const gl
             stream->readInt(&outputs[outputIndex]);
         }
 
         const size_t pixelShaderSize             = stream->readInt<unsigned int>();
         const unsigned char *pixelShaderFunction = binary + stream->offset();
         ShaderExecutableD3D *shaderExecutable    = nullptr;
 
         ANGLE_TRY(mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize,
-                                            gl::SHADER_FRAGMENT, mStreamOutVaryings,
+                                            gl::ShaderType::Fragment, mStreamOutVaryings,
                                             separateAttribs, &shaderExecutable));
 
         if (!shaderExecutable)
         {
             infoLog << "Could not create pixel shader.";
             return false;
         }
 
@@ -1106,17 +1105,17 @@ gl::LinkResult ProgramD3D::load(const gl
         {
             continue;
         }
 
         const unsigned char *geometryShaderFunction = binary + stream->offset();
 
         ShaderExecutableD3D *geometryExecutable = nullptr;
         ANGLE_TRY(mRenderer->loadExecutable(geometryShaderFunction, geometryShaderSize,
-                                            gl::SHADER_GEOMETRY, mStreamOutVaryings,
+                                            gl::ShaderType::Geometry, mStreamOutVaryings,
                                             separateAttribs, &geometryExecutable));
 
         if (!geometryExecutable)
         {
             infoLog << "Could not create geometry shader.";
             return false;
         }
 
@@ -1127,30 +1126,32 @@ gl::LinkResult ProgramD3D::load(const gl
 
     unsigned int computeShaderSize = stream->readInt<unsigned int>();
     if (computeShaderSize > 0)
     {
         const unsigned char *computeShaderFunction = binary + stream->offset();
 
         ShaderExecutableD3D *computeExecutable = nullptr;
         ANGLE_TRY(mRenderer->loadExecutable(computeShaderFunction, computeShaderSize,
-                                            gl::SHADER_COMPUTE, std::vector<D3DVarying>(), false,
-                                            &computeExecutable));
+                                            gl::ShaderType::Compute, std::vector<D3DVarying>(),
+                                            false, &computeExecutable));
 
         if (!computeExecutable)
         {
             infoLog << "Could not create compute shader.";
             return false;
         }
 
         mComputeExecutable.reset(computeExecutable);
     }
 
     initializeUniformStorage();
 
+    dirtyAllUniforms();
+
     return true;
 }
 
 void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream)
 {
     // Output the DeviceIdentifier before we output any shader code
     // When we load the binary again later, we can validate the device identifier before trying to
     // compile any HLSL
@@ -1165,33 +1166,33 @@ void ProgramD3D::save(const gl::Context 
         stream->writeInt(d3dSemantic);
     }
 
     stream->writeInt(mSamplersPS.size());
     for (unsigned int i = 0; i < mSamplersPS.size(); ++i)
     {
         stream->writeInt(mSamplersPS[i].active);
         stream->writeInt(mSamplersPS[i].logicalTextureUnit);
-        stream->writeInt(mSamplersPS[i].textureType);
+        stream->writeEnum(mSamplersPS[i].textureType);
     }
 
     stream->writeInt(mSamplersVS.size());
     for (unsigned int i = 0; i < mSamplersVS.size(); ++i)
     {
         stream->writeInt(mSamplersVS[i].active);
         stream->writeInt(mSamplersVS[i].logicalTextureUnit);
-        stream->writeInt(mSamplersVS[i].textureType);
+        stream->writeEnum(mSamplersVS[i].textureType);
     }
 
     stream->writeInt(mSamplersCS.size());
     for (unsigned int i = 0; i < mSamplersCS.size(); ++i)
     {
         stream->writeInt(mSamplersCS[i].active);
         stream->writeInt(mSamplersCS[i].logicalTextureUnit);
-        stream->writeInt(mSamplersCS[i].textureType);
+        stream->writeEnum(mSamplersCS[i].textureType);
     }
 
     stream->writeInt(mImagesCS.size());
     for (unsigned int i = 0; i < mImagesCS.size(); ++i)
     {
         stream->writeInt(mImagesCS[i].active);
         stream->writeInt(mImagesCS[i].logicalImageUnit);
     }
@@ -1352,17 +1353,17 @@ gl::Error ProgramD3D::getPixelExecutable
 
     // Generate new pixel executable
     ShaderExecutableD3D *pixelExecutable = nullptr;
 
     gl::InfoLog tempInfoLog;
     gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
 
     ANGLE_TRY(mRenderer->compileToExecutable(
-        *currentInfoLog, finalPixelHLSL, gl::SHADER_FRAGMENT, mStreamOutVaryings,
+        *currentInfoLog, finalPixelHLSL, gl::ShaderType::Fragment, mStreamOutVaryings,
         (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), mPixelWorkarounds,
         &pixelExecutable));
 
     if (pixelExecutable)
     {
         mPixelExecutables.push_back(std::unique_ptr<PixelExecutable>(
             new PixelExecutable(mPixelShaderOutputLayoutCache, pixelExecutable)));
         mCachedPixelExecutableIndex = mPixelExecutables.size() - 1;
@@ -1393,17 +1394,17 @@ gl::Error ProgramD3D::getVertexExecutabl
 
     // Generate new vertex executable
     ShaderExecutableD3D *vertexExecutable = nullptr;
 
     gl::InfoLog tempInfoLog;
     gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
 
     ANGLE_TRY(mRenderer->compileToExecutable(
-        *currentInfoLog, finalVertexHLSL, gl::SHADER_VERTEX, mStreamOutVaryings,
+        *currentInfoLog, finalVertexHLSL, gl::ShaderType::Vertex, mStreamOutVaryings,
         (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), mVertexWorkarounds,
         &vertexExecutable));
 
     if (vertexExecutable)
     {
         mVertexExecutables.push_back(std::unique_ptr<VertexExecutable>(
             new VertexExecutable(mCachedInputLayout, mCachedVertexSignature, vertexExecutable)));
         mCachedVertexExecutableIndex = mVertexExecutables.size() - 1;
@@ -1450,17 +1451,17 @@ gl::Error ProgramD3D::getGeometryExecuta
         mHasANGLEMultiviewEnabled, mRenderer->canSelectViewInVertexShader(),
         usesGeometryShaderForPointSpriteEmulation(), mGeometryShaderPreamble);
 
     gl::InfoLog tempInfoLog;
     gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
 
     ShaderExecutableD3D *geometryExecutable = nullptr;
     gl::Error error                         = mRenderer->compileToExecutable(
-        *currentInfoLog, geometryHLSL, gl::SHADER_GEOMETRY, mStreamOutVaryings,
+        *currentInfoLog, geometryHLSL, gl::ShaderType::Geometry, mStreamOutVaryings,
         (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS),
         angle::CompilerWorkaroundsD3D(), &geometryExecutable);
 
     if (!infoLog && error.isError())
     {
         ERR() << "Error compiling dynamic geometry executable:" << std::endl
               << tempInfoLog.str() << std::endl;
     }
@@ -1517,17 +1518,18 @@ class ProgramD3D::GetVertexExecutableTas
     }
 
   private:
     const gl::Context *mContext;
 };
 
 void ProgramD3D::updateCachedInputLayoutFromShader(const gl::Context *context)
 {
-    GetDefaultInputLayoutFromShader(context, mState.getAttachedVertexShader(), &mCachedInputLayout);
+    GetDefaultInputLayoutFromShader(context, mState.getAttachedShader(gl::ShaderType::Vertex),
+                                    &mCachedInputLayout);
     VertexExecutable::getSignature(mRenderer, mCachedInputLayout, &mCachedVertexSignature);
     updateCachedVertexExecutableIndex();
 }
 
 class ProgramD3D::GetPixelExecutableTask : public ProgramD3D::GetExecutableTask
 {
   public:
     GetPixelExecutableTask(ProgramD3D *program) : GetExecutableTask(program) {}
@@ -1616,17 +1618,18 @@ gl::LinkResult ProgramD3D::compileProgra
     ANGLE_TRY(vertexTask.getError());
     ANGLE_TRY(pixelTask.getError());
     ANGLE_TRY(geometryTask.getError());
 
     ShaderExecutableD3D *defaultVertexExecutable = vertexTask.getResult();
     ShaderExecutableD3D *defaultPixelExecutable  = pixelTask.getResult();
     ShaderExecutableD3D *pointGS                 = geometryTask.getResult();
 
-    const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedVertexShader());
+    const ShaderD3D *vertexShaderD3D =
+        GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Vertex));
 
     if (usesGeometryShader(GL_POINTS) && pointGS)
     {
         // Geometry shaders are currently only used internally, so there is no corresponding shader
         // object at the interface level. For now the geometry shader debug info is prepended to
         // the vertex shader.
         vertexShaderD3D->appendDebugInfo("// GEOMETRY SHADER BEGIN\n\n");
         vertexShaderD3D->appendDebugInfo(pointGS->getDebugInfo());
@@ -1636,85 +1639,87 @@ gl::LinkResult ProgramD3D::compileProgra
     if (defaultVertexExecutable)
     {
         vertexShaderD3D->appendDebugInfo(defaultVertexExecutable->getDebugInfo());
     }
 
     if (defaultPixelExecutable)
     {
         const ShaderD3D *fragmentShaderD3D =
-            GetImplAs<ShaderD3D>(mState.getAttachedFragmentShader());
+            GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Fragment));
         fragmentShaderD3D->appendDebugInfo(defaultPixelExecutable->getDebugInfo());
     }
 
     return (defaultVertexExecutable && defaultPixelExecutable &&
             (!usesGeometryShader(GL_POINTS) || pointGS));
 }
 
 gl::LinkResult ProgramD3D::compileComputeExecutable(const gl::Context *context,
                                                     gl::InfoLog &infoLog)
 {
     // Ensure the compiler is initialized to avoid race conditions.
     ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized());
 
     std::string computeShader = mDynamicHLSL->generateComputeShaderLinkHLSL(context, mState);
 
     ShaderExecutableD3D *computeExecutable = nullptr;
-    ANGLE_TRY(mRenderer->compileToExecutable(infoLog, computeShader, gl::SHADER_COMPUTE,
+    ANGLE_TRY(mRenderer->compileToExecutable(infoLog, computeShader, gl::ShaderType::Compute,
                                              std::vector<D3DVarying>(), false,
                                              angle::CompilerWorkaroundsD3D(), &computeExecutable));
 
     if (computeExecutable == nullptr)
     {
         ERR() << "Error compiling dynamic compute executable:" << std::endl
               << infoLog.str() << std::endl;
     }
     else
     {
-        const ShaderD3D *computeShaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedComputeShader());
+        const ShaderD3D *computeShaderD3D =
+            GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Compute));
         computeShaderD3D->appendDebugInfo(computeExecutable->getDebugInfo());
         mComputeExecutable.reset(computeExecutable);
     }
 
     return mComputeExecutable.get() != nullptr;
 }
 
 gl::LinkResult ProgramD3D::link(const gl::Context *context,
                                 const gl::ProgramLinkedResources &resources,
                                 gl::InfoLog &infoLog)
 {
     const auto &data = context->getContextState();
 
     reset();
 
-    gl::Shader *computeShader = mState.getAttachedComputeShader();
+    gl::Shader *computeShader = mState.getAttachedShader(gl::ShaderType::Compute);
     if (computeShader)
     {
         mSamplersCS.resize(data.getCaps().maxComputeTextureImageUnits);
         mImagesCS.resize(data.getCaps().maxImageUnits);
         mReadonlyImagesCS.resize(data.getCaps().maxImageUnits);
 
+        mShaderUniformsDirty.set(gl::ShaderType::Compute);
         defineUniformsAndAssignRegisters(context);
 
         gl::LinkResult result = compileComputeExecutable(context, infoLog);
         if (result.isError())
         {
             infoLog << result.getError().getMessage();
             return result;
         }
         else if (!result.getResult())
         {
             infoLog << "Failed to create D3D compute shader.";
             return result;
         }
     }
     else
     {
-        gl::Shader *vertexShader   = mState.getAttachedVertexShader();
-        gl::Shader *fragmentShader = mState.getAttachedFragmentShader();
+        gl::Shader *vertexShader   = mState.getAttachedShader(gl::ShaderType::Vertex);
+        gl::Shader *fragmentShader = mState.getAttachedShader(gl::ShaderType::Fragment);
 
         const ShaderD3D *vertexShaderD3D   = GetImplAs<ShaderD3D>(vertexShader);
         const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(fragmentShader);
 
         mSamplersVS.resize(data.getCaps().maxVertexTextureImageUnits);
         mSamplersPS.resize(data.getCaps().maxTextureImageUnits);
 
         vertexShaderD3D->generateWorkarounds(&mVertexWorkarounds);
@@ -1750,19 +1755,23 @@ gl::LinkResult ProgramD3D::link(const gl
         {
             mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble(
                 resources.varyingPacking, builtins, mHasANGLEMultiviewEnabled,
                 metadata.canSelectViewInVertexShader());
         }
 
         initAttribLocationsToD3DSemantic(context);
 
+        // TODO(jiawei.shao@intel.com): set geometry uniforms dirty if user-defined geometry shader
+        // exists. Tracking bug: http://anglebug.com/1941
+        mShaderUniformsDirty.set(gl::ShaderType::Vertex);
+        mShaderUniformsDirty.set(gl::ShaderType::Fragment);
         defineUniformsAndAssignRegisters(context);
 
-        gatherTransformFeedbackVaryings(resources.varyingPacking, builtins[gl::SHADER_VERTEX]);
+        gatherTransformFeedbackVaryings(resources.varyingPacking, builtins[gl::ShaderType::Vertex]);
 
         gl::LinkResult result = compileProgramExecutables(context, infoLog);
         if (result.isError())
         {
             infoLog << result.getError().getMessage();
             return result;
         }
         else if (!result.getResult())
@@ -1788,43 +1797,45 @@ void ProgramD3D::initializeUniformBlocks
     if (mState.getUniformBlocks().empty())
     {
         return;
     }
 
     ASSERT(mD3DUniformBlocks.empty());
 
     // Assign registers and update sizes.
-    const ShaderD3D *vertexShaderD3D = SafeGetImplAs<ShaderD3D>(mState.getAttachedVertexShader());
+    const ShaderD3D *vertexShaderD3D =
+        SafeGetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Vertex));
     const ShaderD3D *fragmentShaderD3D =
-        SafeGetImplAs<ShaderD3D>(mState.getAttachedFragmentShader());
-    const ShaderD3D *computeShaderD3D = SafeGetImplAs<ShaderD3D>(mState.getAttachedComputeShader());
+        SafeGetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Fragment));
+    const ShaderD3D *computeShaderD3D =
+        SafeGetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Compute));
 
     for (const gl::InterfaceBlock &uniformBlock : mState.getUniformBlocks())
     {
         unsigned int uniformBlockElement = uniformBlock.isArray ? uniformBlock.arrayElement : 0;
 
         D3DUniformBlock d3dUniformBlock;
 
-        if (uniformBlock.vertexStaticUse)
+        if (uniformBlock.isActive(gl::ShaderType::Vertex))
         {
             ASSERT(vertexShaderD3D != nullptr);
             unsigned int baseRegister = vertexShaderD3D->getUniformBlockRegister(uniformBlock.name);
             d3dUniformBlock.vsRegisterIndex = baseRegister + uniformBlockElement;
         }
 
-        if (uniformBlock.fragmentStaticUse)
+        if (uniformBlock.isActive(gl::ShaderType::Fragment))
         {
             ASSERT(fragmentShaderD3D != nullptr);
             unsigned int baseRegister =
                 fragmentShaderD3D->getUniformBlockRegister(uniformBlock.name);
             d3dUniformBlock.psRegisterIndex = baseRegister + uniformBlockElement;
         }
 
-        if (uniformBlock.computeStaticUse)
+        if (uniformBlock.isActive(gl::ShaderType::Compute))
         {
             ASSERT(computeShaderD3D != nullptr);
             unsigned int baseRegister =
                 computeShaderD3D->getUniformBlockRegister(uniformBlock.name);
             d3dUniformBlock.csRegisterIndex = baseRegister + uniformBlockElement;
         }
 
         mD3DUniformBlocks.push_back(d3dUniformBlock);
@@ -1909,36 +1920,36 @@ void ProgramD3D::updateUniformBufferCach
 
     for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mD3DUniformBlocks.size();
          uniformBlockIndex++)
     {
         const D3DUniformBlock &uniformBlock = mD3DUniformBlocks[uniformBlockIndex];
         GLuint blockBinding                 = mState.getUniformBlockBinding(uniformBlockIndex);
 
         // Unnecessary to apply an unreferenced standard or shared UBO
-        if (!uniformBlock.vertexStaticUse() && !uniformBlock.fragmentStaticUse())
+        if (!uniformBlock.vertexActive() && !uniformBlock.fragmentActive())
         {
             continue;
         }
 
-        if (uniformBlock.vertexStaticUse())
+        if (uniformBlock.vertexActive())
         {
             unsigned int registerIndex = uniformBlock.vsRegisterIndex - reservedVertex;
             ASSERT(registerIndex < caps.maxVertexUniformBlocks);
 
             if (mVertexUBOCache.size() <= registerIndex)
             {
                 mVertexUBOCache.resize(registerIndex + 1, -1);
             }
 
             ASSERT(mVertexUBOCache[registerIndex] == -1);
             mVertexUBOCache[registerIndex] = blockBinding;
         }
 
-        if (uniformBlock.fragmentStaticUse())
+        if (uniformBlock.fragmentActive())
         {
             unsigned int registerIndex = uniformBlock.psRegisterIndex - reservedFragment;
             ASSERT(registerIndex < caps.maxFragmentUniformBlocks);
 
             if (mFragmentUBOCache.size() <= registerIndex)
             {
                 mFragmentUBOCache.resize(registerIndex + 1, -1);
             }
@@ -1956,26 +1967,22 @@ const std::vector<GLint> &ProgramD3D::ge
 
 const std::vector<GLint> &ProgramD3D::getFragmentUniformBufferCache() const
 {
     return mFragmentUBOCache;
 }
 
 void ProgramD3D::dirtyAllUniforms()
 {
-    mVertexUniformsDirty   = true;
-    mFragmentUniformsDirty = true;
-    mComputeUniformsDirty  = true;
+    mShaderUniformsDirty = mState.getLinkedShaderStages();
 }
 
 void ProgramD3D::markUniformsClean()
 {
-    mVertexUniformsDirty   = false;
-    mFragmentUniformsDirty = false;
-    mComputeUniformsDirty  = false;
+    mShaderUniformsDirty.reset();
 }
 
 void ProgramD3D::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
 {
     setUniformInternal(location, count, v, GL_FLOAT);
 }
 
 void ProgramD3D::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
@@ -2108,44 +2115,27 @@ void ProgramD3D::setUniform4uiv(GLint lo
 void ProgramD3D::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint /*uniformBlockBinding*/)
 {
     mRenderer->onDirtyUniformBlockBinding(uniformBlockIndex);
 }
 
 void ProgramD3D::defineUniformsAndAssignRegisters(const gl::Context *context)
 {
     D3DUniformMap uniformMap;
-    gl::Shader *computeShader = mState.getAttachedComputeShader();
-    if (computeShader)
-    {
-        for (const sh::Uniform &computeUniform : computeShader->getUniforms(context))
-        {
-            if (computeUniform.staticUse)
-            {
-                defineUniformBase(computeShader, computeUniform, &uniformMap);
-            }
-        }
-    }
-    else
+    for (gl::ShaderType shaderType : gl::AllShaderTypes())
     {
-        gl::Shader *vertexShader = mState.getAttachedVertexShader();
-        for (const sh::Uniform &vertexUniform : vertexShader->getUniforms(context))
+        gl::Shader *shader = mState.getAttachedShader(shaderType);
+        if (shader)
         {
-            if (vertexUniform.staticUse)
+            for (const sh::Uniform &uniform : shader->getUniforms(context))
             {
-                defineUniformBase(vertexShader, vertexUniform, &uniformMap);
-            }
-        }
-
-        gl::Shader *fragmentShader = mState.getAttachedFragmentShader();
-        for (const sh::Uniform &fragmentUniform : fragmentShader->getUniforms(context))
-        {
-            if (fragmentUniform.staticUse)
-            {
-                defineUniformBase(fragmentShader, fragmentUniform, &uniformMap);
+                if (uniform.active)
+                {
+                    defineUniformBase(shader, uniform, &uniformMap);
+                }
             }
         }
     }
 
     // Initialize the D3DUniform list to mirror the indexing of the GL layer.
     for (const gl::LinkedUniform &glUniform : mState.getUniforms())
     {
         if (!glUniform.isInDefaultBlock())
@@ -2223,17 +2213,17 @@ D3DUniform *ProgramD3D::getD3DUniformByN
         {
             return d3dUniform;
         }
     }
 
     return nullptr;
 }
 
-void ProgramD3D::defineStructUniformFields(GLenum shaderType,
+void ProgramD3D::defineStructUniformFields(gl::ShaderType shaderType,
                                            const std::vector<sh::ShaderVariable> &fields,
                                            const std::string &namePrefix,
                                            const HLSLRegisterType regType,
                                            sh::HLSLBlockEncoder *encoder,
                                            D3DUniformMap *uniformMap)
 {
     if (encoder)
         encoder->enterAggregateType();
@@ -2255,17 +2245,17 @@ void ProgramD3D::defineStructUniformFiel
             defineUniform(shaderType, field, fieldFullName, regType, encoder, uniformMap);
         }
     }
 
     if (encoder)
         encoder->exitAggregateType();
 }
 
-void ProgramD3D::defineArrayOfStructsUniformFields(GLenum shaderType,
+void ProgramD3D::defineArrayOfStructsUniformFields(gl::ShaderType shaderType,
                                                    const sh::ShaderVariable &uniform,
                                                    unsigned int arrayNestingIndex,
                                                    const std::string &prefix,
                                                    const HLSLRegisterType regType,
                                                    sh::HLSLBlockEncoder *encoder,
                                                    D3DUniformMap *uniformMap)
 {
     // Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the
@@ -2282,17 +2272,17 @@ void ProgramD3D::defineArrayOfStructsUni
         else
         {
             defineStructUniformFields(shaderType, uniform.fields, elementString, regType, encoder,
                                       uniformMap);
         }
     }
 }
 
-void ProgramD3D::defineArrayUniformElements(GLenum shaderType,
+void ProgramD3D::defineArrayUniformElements(gl::ShaderType shaderType,
                                             const sh::ShaderVariable &uniform,
                                             const std::string &fullName,
                                             const HLSLRegisterType regType,
                                             sh::HLSLBlockEncoder *encoder,
                                             D3DUniformMap *uniformMap)
 {
     if (encoder)
         encoder->enterAggregateType();
@@ -2304,17 +2294,17 @@ void ProgramD3D::defineArrayUniformEleme
         std::string elementFullName = fullName + ArrayString(arrayIndex);
         defineUniform(shaderType, uniformElement, elementFullName, regType, encoder, uniformMap);
     }
 
     if (encoder)
         encoder->exitAggregateType();
 }
 
-void ProgramD3D::defineUniform(GLenum shaderType,
+void ProgramD3D::defineUniform(gl::ShaderType shaderType,
                                const sh::ShaderVariable &uniform,
                                const std::string &fullName,
                                const HLSLRegisterType regType,
                                sh::HLSLBlockEncoder *encoder,
                                D3DUniformMap *uniformMap)
 {
     if (uniform.isStruct())
     {
@@ -2361,28 +2351,30 @@ void ProgramD3D::defineUniform(GLenum sh
     }
 
     if (encoder)
     {
         d3dUniform->registerElement =
             static_cast<unsigned int>(sh::HLSLBlockEncoder::getBlockRegisterElement(blockInfo));
         unsigned int reg =
             static_cast<unsigned int>(sh::HLSLBlockEncoder::getBlockRegister(blockInfo));
-        if (shaderType == GL_FRAGMENT_SHADER)
-        {
-            d3dUniform->psRegisterIndex = reg;
-        }
-        else if (shaderType == GL_VERTEX_SHADER)
+
+        switch (shaderType)
         {
-            d3dUniform->vsRegisterIndex = reg;
-        }
-        else
-        {
-            ASSERT(shaderType == GL_COMPUTE_SHADER);
-            d3dUniform->csRegisterIndex = reg;
+            case gl::ShaderType::Fragment:
+                d3dUniform->psRegisterIndex = reg;
+                break;
+            case gl::ShaderType::Vertex:
+                d3dUniform->vsRegisterIndex = reg;
+                break;
+            case gl::ShaderType::Compute:
+                d3dUniform->csRegisterIndex = reg;
+                break;
+            default:
+                UNREACHABLE();
         }
 
         // Arrays are treated as aggregate types
         if (uniform.isArray())
         {
             encoder->exitAggregateType();
         }
     }
@@ -2445,29 +2437,29 @@ void ProgramD3D::setUniformInternal(GLin
             mDirtySamplerMapping = true;
         }
         return;
     }
 
     if (targetUniform->vsData)
     {
         setUniformImpl(locationInfo, count, v, targetUniform->vsData, uniformType);
-        mVertexUniformsDirty = true;
+        mShaderUniformsDirty.set(gl::ShaderType::Vertex);
     }
 
     if (targetUniform->psData)
     {
         setUniformImpl(locationInfo, count, v, targetUniform->psData, uniformType);
-        mFragmentUniformsDirty = true;
+        mShaderUniformsDirty.set(gl::ShaderType::Fragment);
     }
 
     if (targetUniform->csData)
     {
         setUniformImpl(locationInfo, count, v, targetUniform->csData, uniformType);
-        mComputeUniformsDirty = true;
+        mShaderUniformsDirty.set(gl::ShaderType::Compute);
     }
 }
 
 template <int cols, int rows>
 bool ProgramD3D::setUniformMatrixfvImpl(GLint location,
                                         GLsizei countIn,
                                         GLboolean transpose,
                                         const GLfloat *value,
@@ -2514,35 +2506,35 @@ void ProgramD3D::setUniformMatrixfvInter
 {
     D3DUniform *targetUniform = getD3DUniformFromLocation(location);
 
     if (targetUniform->vsData)
     {
         if (setUniformMatrixfvImpl<cols, rows>(location, countIn, transpose, value,
                                                targetUniform->vsData, targetUniformType))
         {
-            mVertexUniformsDirty = true;
+            mShaderUniformsDirty.set(gl::ShaderType::Vertex);
         }
     }
 
     if (targetUniform->psData)
     {
         if (setUniformMatrixfvImpl<cols, rows>(location, countIn, transpose, value,
                                                targetUniform->psData, targetUniformType))
         {
-            mFragmentUniformsDirty = true;
+            mShaderUniformsDirty.set(gl::ShaderType::Fragment);
         }
     }
 
     if (targetUniform->csData)
     {
         if (setUniformMatrixfvImpl<cols, rows>(location, countIn, transpose, value,
                                                targetUniform->csData, targetUniformType))
         {
-            mComputeUniformsDirty = true;
+            mShaderUniformsDirty.set(gl::ShaderType::Compute);
         }
     }
 }
 
 void ProgramD3D::assignAllSamplerRegisters()
 {
     for (size_t uniformIndex = 0; uniformIndex < mD3DUniforms.size(); ++uniformIndex)
     {
@@ -2560,32 +2552,34 @@ void ProgramD3D::assignSamplerRegisters(
     // If the uniform is an array of arrays, then we have separate entries for each inner array in
     // mD3DUniforms. However, the sampler register info is stored in the shader only for the
     // outermost array.
     std::vector<unsigned int> subscripts;
     const std::string baseName  = gl::ParseResourceName(d3dUniform->name, &subscripts);
     unsigned int registerOffset = mState.getUniforms()[uniformIndex].flattenedOffsetInParentArrays *
                                   d3dUniform->getArraySizeProduct();
 
-    const gl::Shader *computeShader = mState.getAttachedComputeShader();
+    const gl::Shader *computeShader = mState.getAttachedShader(gl::ShaderType::Compute);
     if (computeShader)
     {
-        const ShaderD3D *computeShaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedComputeShader());
+        const ShaderD3D *computeShaderD3D =
+            GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Compute));
         ASSERT(computeShaderD3D->hasUniform(baseName));
         d3dUniform->csRegisterIndex =
             computeShaderD3D->getUniformRegister(baseName) + registerOffset;
         ASSERT(d3dUniform->csRegisterIndex != GL_INVALID_INDEX);
         AssignSamplers(d3dUniform->csRegisterIndex, d3dUniform->typeInfo,
                        d3dUniform->getArraySizeProduct(), mSamplersCS, &mUsedComputeSamplerRange);
     }
     else
     {
-        const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedVertexShader());
+        const ShaderD3D *vertexShaderD3D =
+            GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Vertex));
         const ShaderD3D *fragmentShaderD3D =
-            GetImplAs<ShaderD3D>(mState.getAttachedFragmentShader());
+            GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Fragment));
         ASSERT(vertexShaderD3D->hasUniform(baseName) || fragmentShaderD3D->hasUniform(baseName));
         if (vertexShaderD3D->hasUniform(baseName))
         {
             d3dUniform->vsRegisterIndex =
                 vertexShaderD3D->getUniformRegister(baseName) + registerOffset;
             ASSERT(d3dUniform->vsRegisterIndex != GL_INVALID_INDEX);
             AssignSamplers(d3dUniform->vsRegisterIndex, d3dUniform->typeInfo,
                            d3dUniform->getArraySizeProduct(), mSamplersVS,
@@ -2611,17 +2605,17 @@ void ProgramD3D::AssignSamplers(unsigned
 {
     unsigned int samplerIndex = startSamplerIndex;
 
     do
     {
         ASSERT(samplerIndex < outSamplers.size());
         Sampler *sampler            = &outSamplers[samplerIndex];
         sampler->active             = true;
-        sampler->textureType        = typeInfo.textureType;
+        sampler->textureType        = gl::FromGLenum<gl::TextureType>(typeInfo.textureType);
         sampler->logicalTextureUnit = 0;
         *outUsedRange               = std::max(samplerIndex + 1, *outUsedRange);
         samplerIndex++;
     } while (samplerIndex < startSamplerIndex + samplerCount);
 }
 
 void ProgramD3D::assignAllImageRegisters()
 {
@@ -2641,20 +2635,21 @@ void ProgramD3D::assignImageRegisters(si
     // If the uniform is an array of arrays, then we have separate entries for each inner array in
     // mD3DUniforms. However, the image register info is stored in the shader only for the
     // outermost array.
     std::vector<unsigned int> subscripts;
     const std::string baseName  = gl::ParseResourceName(d3dUniform->name, &subscripts);
     unsigned int registerOffset = mState.getUniforms()[uniformIndex].flattenedOffsetInParentArrays *
                                   d3dUniform->getArraySizeProduct();
 
-    const gl::Shader *computeShader = mState.getAttachedComputeShader();
+    const gl::Shader *computeShader = mState.getAttachedShader(gl::ShaderType::Compute);
     if (computeShader)
     {
-        const ShaderD3D *computeShaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedComputeShader());
+        const ShaderD3D *computeShaderD3D =
+            GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Compute));
         ASSERT(computeShaderD3D->hasUniform(baseName));
         d3dUniform->csRegisterIndex =
             computeShaderD3D->getUniformRegister(baseName) + registerOffset;
         ASSERT(d3dUniform->csRegisterIndex != GL_INVALID_INDEX);
         auto bindingIter = mImageBindingMap.find(baseName);
         ASSERT(bindingIter != mImageBindingMap.end());
         if (d3dUniform->regType == HLSLRegisterType::Texture)
         {
@@ -2757,17 +2752,17 @@ void ProgramD3D::reset()
     mUsedComputeReadonlyImageRange = 0;
 
     mAttribLocationToD3DSemantic.fill(-1);
 
     mStreamOutVaryings.clear();
 
     mGeometryShaderPreamble.clear();
 
-    dirtyAllUniforms();
+    markUniformsClean();
 
     mCachedPixelExecutableIndex.reset();
     mCachedVertexExecutableIndex.reset();
 }
 
 unsigned int ProgramD3D::getSerial() const
 {
     return mSerial;
@@ -2775,17 +2770,17 @@ unsigned int ProgramD3D::getSerial() con
 
 unsigned int ProgramD3D::issueSerial()
 {
     return mCurrentSerial++;
 }
 
 void ProgramD3D::initAttribLocationsToD3DSemantic(const gl::Context *context)
 {
-    gl::Shader *vertexShader = mState.getAttachedVertexShader();
+    gl::Shader *vertexShader = mState.getAttachedShader(gl::ShaderType::Vertex);
     ASSERT(vertexShader != nullptr);
 
     // Init semantic index
     int semanticIndex = 0;
     for (const sh::Attribute &attribute : vertexShader->getActiveAttributes(context))
     {
         int regCount    = gl::VariableRegisterCount(attribute.type);
         GLuint location = mState.getAttributeLocation(attribute.name);
@@ -2951,16 +2946,21 @@ bool ProgramD3D::hasGeometryExecutableFo
     return mGeometryExecutables[geometryShaderType].get() != nullptr;
 }
 
 bool ProgramD3D::hasPixelExecutableForCachedOutputLayout()
 {
     return mCachedPixelExecutableIndex.valid();
 }
 
+bool ProgramD3D::anyShaderUniformsDirty() const
+{
+    return mShaderUniformsDirty.any();
+}
+
 template <typename DestT>
 void ProgramD3D::getUniformInternal(GLint location, DestT *dataOut) const
 {
     const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
     const gl::LinkedUniform &uniform         = mState.getUniforms()[locationInfo.index];
 
     const D3DUniform *targetUniform = getD3DUniformFromLocation(location);
     const uint8_t *srcPointer       = targetUniform->getDataPtrToElement(locationInfo.arrayIndex);
@@ -3016,30 +3016,23 @@ void ProgramD3D::updateCachedPixelExecut
         }
     }
 }
 
 void ProgramD3D::linkResources(const gl::Context *context,
                                const gl::ProgramLinkedResources &resources)
 {
     UniformBlockInfo uniformBlockInfo;
-
-    if (mState.getAttachedVertexShader())
+    for (gl::ShaderType shaderType : gl::AllShaderTypes())
     {
-        uniformBlockInfo.getShaderBlockInfo(context, mState.getAttachedVertexShader());
-    }
-
-    if (mState.getAttachedFragmentShader())
-    {
-        uniformBlockInfo.getShaderBlockInfo(context, mState.getAttachedFragmentShader());
-    }
-
-    if (mState.getAttachedComputeShader())
-    {
-        uniformBlockInfo.getShaderBlockInfo(context, mState.getAttachedComputeShader());
+        gl::Shader *shader = mState.getAttachedShader(shaderType);
+        if (shader)
+        {
+            uniformBlockInfo.getShaderBlockInfo(context, shader);
+        }
     }
 
     // Gather interface block info.
     auto getUniformBlockSize = [&uniformBlockInfo](const std::string &name,
                                                    const std::string &mappedName, size_t *sizeOut) {
         return uniformBlockInfo.getBlockSize(name, mappedName, sizeOut);
     };
 
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.h
@@ -92,21 +92,21 @@ struct D3DUniformBlock
 {
     D3DUniformBlock()
         : vsRegisterIndex(GL_INVALID_INDEX),
           psRegisterIndex(GL_INVALID_INDEX),
           csRegisterIndex(GL_INVALID_INDEX)
     {
     }
 
-    bool vertexStaticUse() const { return vsRegisterIndex != GL_INVALID_INDEX; }
+    bool vertexActive() const { return vsRegisterIndex != GL_INVALID_INDEX; }
 
-    bool fragmentStaticUse() const { return psRegisterIndex != GL_INVALID_INDEX; }
+    bool fragmentActive() const { return psRegisterIndex != GL_INVALID_INDEX; }
 
-    bool computeStaticUse() const { return csRegisterIndex != GL_INVALID_INDEX; }
+    bool computeActive() const { return csRegisterIndex != GL_INVALID_INDEX; }
 
     unsigned int vsRegisterIndex;
     unsigned int psRegisterIndex;
     unsigned int csRegisterIndex;
 };
 
 struct D3DVarying final
 {
@@ -168,17 +168,17 @@ class ProgramD3D : public ProgramImpl
     ProgramD3D(const gl::ProgramState &data, RendererD3D *renderer);
     ~ProgramD3D() override;
 
     const std::vector<PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
 
     GLint getSamplerMapping(gl::ShaderType type,
                             unsigned int samplerIndex,
                             const gl::Caps &caps) const;
-    GLenum getSamplerTextureType(gl::ShaderType type, unsigned int samplerIndex) const;
+    gl::TextureType getSamplerTextureType(gl::ShaderType type, unsigned int samplerIndex) const;
     GLuint getUsedSamplerRange(gl::ShaderType type) const;
 
     enum SamplerMapping
     {
         WasDirty,
         WasClean,
     };
 
@@ -303,19 +303,21 @@ class ProgramD3D : public ProgramImpl
 
     bool isSamplerMappingDirty() { return mDirtySamplerMapping; }
 
     // Checks if we need to recompile certain shaders.
     bool hasVertexExecutableForCachedInputLayout();
     bool hasGeometryExecutableForPrimitiveType(GLenum drawMode);
     bool hasPixelExecutableForCachedOutputLayout();
 
-    bool areVertexUniformsDirty() const { return mVertexUniformsDirty; }
-    bool areFragmentUniformsDirty() const { return mFragmentUniformsDirty; }
-    bool areComputeUniformsDirty() const { return mComputeUniformsDirty; }
+    bool anyShaderUniformsDirty() const;
+    bool areShaderUniformsDirty(gl::ShaderType shaderType) const
+    {
+        return mShaderUniformsDirty[shaderType];
+    }
     const std::vector<D3DUniform *> &getD3DUniforms() const { return mD3DUniforms; }
     void markUniformsClean();
 
   private:
     // These forward-declared tasks are used for multi-thread shader compiles.
     class GetExecutableTask;
     class GetVertexExecutableTask;
     class GetPixelExecutableTask;
@@ -376,52 +378,52 @@ class ProgramD3D : public ProgramImpl
     };
 
     struct Sampler
     {
         Sampler();
 
         bool active;
         GLint logicalTextureUnit;
-        GLenum textureType;
+        gl::TextureType textureType;
     };
 
     struct Image
     {
         Image();
         bool active;
         GLint logicalImageUnit;
     };
 
     typedef std::map<std::string, D3DUniform *> D3DUniformMap;
 
     void defineUniformsAndAssignRegisters(const gl::Context *context);
     void defineUniformBase(const gl::Shader *shader,
                            const sh::Uniform &uniform,
                            D3DUniformMap *uniformMap);
-    void defineStructUniformFields(GLenum shaderType,
+    void defineStructUniformFields(gl::ShaderType shaderType,
                                    const std::vector<sh::ShaderVariable> &fields,
                                    const std::string &namePrefix,
                                    const HLSLRegisterType regType,
                                    sh::HLSLBlockEncoder *encoder,
                                    D3DUniformMap *uniformMap);
-    void defineArrayOfStructsUniformFields(GLenum shaderType,
+    void defineArrayOfStructsUniformFields(gl::ShaderType shaderType,
                                            const sh::ShaderVariable &uniform,
                                            unsigned int arrayNestingIndex,
                                            const std::string &prefix,
                                            const HLSLRegisterType regType,
                                            sh::HLSLBlockEncoder *encoder,
                                            D3DUniformMap *uniformMap);
-    void defineArrayUniformElements(GLenum shaderType,
+    void defineArrayUniformElements(gl::ShaderType shaderType,
                                     const sh::ShaderVariable &uniform,
                                     const std::string &fullName,
                                     const HLSLRegisterType regType,
                                     sh::HLSLBlockEncoder *encoder,
                                     D3DUniformMap *uniformMap);
-    void defineUniform(GLenum shaderType,
+    void defineUniform(gl::ShaderType shaderType,
                        const sh::ShaderVariable &uniform,
                        const std::string &fullName,
                        const HLSLRegisterType regType,
                        sh::HLSLBlockEncoder *encoder,
                        D3DUniformMap *uniformMap);
     void assignAllSamplerRegisters();
     void assignSamplerRegisters(size_t uniformIndex);
 
@@ -545,19 +547,17 @@ class ProgramD3D : public ProgramImpl
     gl::InputLayout mCachedInputLayout;
     Optional<size_t> mCachedVertexExecutableIndex;
 
     std::vector<D3DVarying> mStreamOutVaryings;
     std::vector<D3DUniform *> mD3DUniforms;
     std::map<std::string, int> mImageBindingMap;
     std::vector<D3DUniformBlock> mD3DUniformBlocks;
 
-    bool mVertexUniformsDirty;
-    bool mFragmentUniformsDirty;
-    bool mComputeUniformsDirty;
+    gl::ShaderBitSet mShaderUniformsDirty;
 
     static unsigned int issueSerial();
     static unsigned int mCurrentSerial;
 
     Serial mCurrentVertexArrayStateSerial;
 };
 }  // namespace rx
 
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.h
@@ -29,19 +29,16 @@ class RenderTargetD3D : public Framebuff
     virtual GLenum getInternalFormat() const = 0;
     virtual GLsizei getSamples() const = 0;
     gl::Extents getExtents() const { return gl::Extents(getWidth(), getHeight(), getDepth()); }
     bool isMultisampled() const { return getSamples() > 0; }
 
     virtual unsigned int getSerial() const;
     static unsigned int issueSerials(unsigned int count);
 
-    // Only currently applies to D3D11.
-    virtual void signalDirty(const gl::Context *context) {}
-
   private:
     const unsigned int mSerial;
     static unsigned int mCurrentSerial;
 };
 
 }
 
 #endif // LIBANGLE_RENDERER_D3D_RENDERTARGETD3D_H_
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp
@@ -107,19 +107,19 @@ gl::Error RenderbufferD3D::getAttachment
                                                      const gl::ImageIndex & /*imageIndex*/,
                                                      FramebufferAttachmentRenderTarget **rtOut)
 {
     return getRenderTarget(context, reinterpret_cast<RenderTargetD3D **>(rtOut));
 }
 
 void RenderbufferD3D::deleteRenderTarget(const gl::Context *context)
 {
+    onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
     if (mRenderTarget)
     {
-        mRenderTarget->signalDirty(context);
         SafeDelete(mRenderTarget);
     }
 }
 
 gl::Error RenderbufferD3D::initializeContents(const gl::Context *context,
                                               const gl::ImageIndex &imageIndex)
 {
     RenderTargetD3D *renderTarget = nullptr;
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.cpp
@@ -78,17 +78,17 @@ bool RendererD3D::skipDraw(const gl::Sta
             return true;
         }
     }
 
     return false;
 }
 
 gl::Error RendererD3D::getIncompleteTexture(const gl::Context *context,
-                                            GLenum type,
+                                            gl::TextureType type,
                                             gl::Texture **textureOut)
 {
     return mIncompleteTextures.getIncompleteTexture(context, type, this, textureOut);
 }
 
 GLenum RendererD3D::getResetStatus()
 {
     if (!mDeviceLost)
@@ -203,17 +203,17 @@ bool InstancedPointSpritesActive(Program
 gl::Error RendererD3D::initRenderTarget(RenderTargetD3D *renderTarget)
 {
     return clearRenderTarget(renderTarget, gl::ColorF(0, 0, 0, 0), 1, 0);
 }
 
 gl::Error RendererD3D::initializeMultisampleTextureToBlack(const gl::Context *context,
                                                            gl::Texture *glTexture)
 {
-    ASSERT(glTexture->getTarget() == GL_TEXTURE_2D_MULTISAMPLE);
+    ASSERT(glTexture->getType() == gl::TextureType::_2DMultisample);
     TextureD3D *textureD3D        = GetImplAs<TextureD3D>(glTexture);
     gl::ImageIndex index          = gl::ImageIndex::Make2DMultisample();
     RenderTargetD3D *renderTarget = nullptr;
     ANGLE_TRY(textureD3D->getRenderTarget(context, index, &renderTarget));
     return clearRenderTarget(renderTarget, gl::ColorF(0.0f, 0.0f, 0.0f, 1.0f), 1.0f, 0);
 }
 
 void RendererD3D::onDirtyUniformBlockBinding(GLuint /*uniformBlockIndex*/)
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.h
@@ -87,17 +87,17 @@ class BufferFactoryD3D : angle::NonCopya
     virtual VertexConversionType getVertexConversionType(gl::VertexFormatType vertexFormatType) const = 0;
     virtual GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const = 0;
 
     // Warning: you should ensure binding really matches attrib.bindingIndex before using this
     // function.
     virtual gl::ErrorOrResult<unsigned int> getVertexSpaceRequired(
         const gl::VertexAttribute &attrib,
         const gl::VertexBinding &binding,
-        GLsizei count,
+        size_t count,
         GLsizei instances) const = 0;
 };
 
 using AttribIndexArray = gl::AttribArray<int>;
 
 class RendererD3D : public BufferFactoryD3D, public MultisampleTextureInitializer
 {
   public:
@@ -153,18 +153,18 @@ class RendererD3D : public BufferFactory
                                   TextureStorage *storage,
                                   GLint level) = 0;
     virtual gl::Error copyImageCube(const gl::Context *context,
                                     const gl::Framebuffer *framebuffer,
                                     const gl::Rectangle &sourceRect,
                                     GLenum destFormat,
                                     const gl::Offset &destOffset,
                                     TextureStorage *storage,
-                                    GLenum target,
-                                    GLint level) = 0;
+                                    gl::TextureTarget target,
+                                    GLint level)    = 0;
     virtual gl::Error copyImage3D(const gl::Context *context,
                                   const gl::Framebuffer *framebuffer,
                                   const gl::Rectangle &sourceRect,
                                   GLenum destFormat,
                                   const gl::Offset &destOffset,
                                   TextureStorage *storage,
                                   GLint level) = 0;
     virtual gl::Error copyImage2DArray(const gl::Context *context,
@@ -178,17 +178,17 @@ class RendererD3D : public BufferFactory
     virtual gl::Error copyTexture(const gl::Context *context,
                                   const gl::Texture *source,
                                   GLint sourceLevel,
                                   const gl::Rectangle &sourceRect,
                                   GLenum destFormat,
                                   GLenum destType,
                                   const gl::Offset &destOffset,
                                   TextureStorage *storage,
-                                  GLenum destTarget,
+                                  gl::TextureTarget destTarget,
                                   GLint destLevel,
                                   bool unpackFlipY,
                                   bool unpackPremultiplyAlpha,
                                   bool unpackUnmultiplyAlpha) = 0;
     virtual gl::Error copyCompressedTexture(const gl::Context *context,
                                             const gl::Texture *source,
                                             GLint sourceLevel,
                                             TextureStorage *storage,
@@ -298,17 +298,17 @@ class RendererD3D : public BufferFactory
 
     virtual gl::Version getMaxSupportedESVersion() const = 0;
 
     gl::Error initRenderTarget(RenderTargetD3D *renderTarget);
 
     angle::WorkerThreadPool *getWorkerThreadPool();
 
     gl::Error getIncompleteTexture(const gl::Context *context,
-                                   GLenum type,
+                                   gl::TextureType type,
                                    gl::Texture **textureOut);
 
     Serial generateSerial();
 
     virtual bool canSelectViewInVertexShader() const = 0;
 
     gl::Error initializeMultisampleTextureToBlack(const gl::Context *context,
                                                   gl::Texture *glTexture) override;
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.cpp
@@ -43,17 +43,17 @@ ShaderD3D::ShaderD3D(const gl::ShaderSta
     if (workarounds.rewriteUnaryMinusOperator)
     {
         mAdditionalOptions |= SH_REWRITE_INTEGER_UNARY_MINUS_OPERATOR;
     }
     if (workarounds.emulateIsnanFloat)
     {
         mAdditionalOptions |= SH_EMULATE_ISNAN_FLOAT_FUNCTION;
     }
-    if (workarounds.skipVSConstantRegisterZero && mData.getShaderType() == GL_VERTEX_SHADER)
+    if (workarounds.skipVSConstantRegisterZero && mData.getShaderType() == gl::ShaderType::Vertex)
     {
         mAdditionalOptions |= SH_SKIP_D3D_CONSTANT_REGISTER_ZERO;
     }
     if (extensions.multiview)
     {
         mAdditionalOptions |= SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW;
     }
 }
@@ -199,17 +199,17 @@ bool ShaderD3D::postTranslateCompile(gl:
         translatedSource.find("ANGLE_REQUIRES_IEEE_STRICT_COMPILING") != std::string::npos;
 
     ShHandle compilerHandle = compiler->getCompilerHandle(mData.getShaderType());
 
     mUniformRegisterMap = GetUniformRegisterMap(sh::GetUniformRegisterMap(compilerHandle));
 
     for (const sh::InterfaceBlock &interfaceBlock : mData.getUniformBlocks())
     {
-        if (interfaceBlock.staticUse)
+        if (interfaceBlock.active)
         {
             unsigned int index = static_cast<unsigned int>(-1);
             bool blockRegisterResult =
                 sh::GetUniformBlockRegister(compilerHandle, interfaceBlock.name, &index);
             ASSERT(blockRegisterResult);
 
             mUniformBlockRegisterMap[interfaceBlock.name] = index;
         }
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.cpp
@@ -159,27 +159,27 @@ GLint TextureD3D::getBaseLevelDepth() co
 // the base level image for anything except querying texture format and size.
 GLenum TextureD3D::getBaseLevelInternalFormat() const
 {
     const ImageD3D *baseImage = getBaseLevelImage();
     return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
 }
 
 gl::Error TextureD3D::setStorage(const gl::Context *context,
-                                 GLenum target,
+                                 gl::TextureType type,
                                  size_t levels,
                                  GLenum internalFormat,
                                  const gl::Extents &size)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D::setStorageMultisample(const gl::Context *context,
-                                            GLenum target,
+                                            gl::TextureType type,
                                             GLsizei samples,
                                             GLint internalFormat,
                                             const gl::Extents &size,
                                             bool fixedSampleLocations)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
@@ -410,17 +410,17 @@ ImageD3D *TextureD3D::getBaseLevelImage(
     if (mBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
     {
         return nullptr;
     }
     return getImage(getImageIndex(mBaseLevel, 0));
 }
 
 gl::Error TextureD3D::setImageExternal(const gl::Context *context,
-                                       GLenum target,
+                                       gl::TextureType type,
                                        egl::Stream *stream,
                                        const egl::Stream::GLTextureDescription &desc)
 {
     // Only external images can accept external textures
     UNREACHABLE();
     return gl::InternalError();
 }
 
@@ -523,32 +523,27 @@ gl::Error TextureD3D::generateMipmapUsin
 
     return gl::NoError();
 }
 
 bool TextureD3D::isBaseImageZeroSize() const
 {
     ImageD3D *baseImage = getBaseLevelImage();
 
-    if (!baseImage || baseImage->getWidth() <= 0)
+    if (!baseImage || baseImage->getWidth() <= 0 || baseImage->getHeight() <= 0)
     {
         return true;
     }
 
-    if (!gl::IsCubeMapTextureTarget(baseImage->getTarget()) && baseImage->getHeight() <= 0)
+    if (baseImage->getType() == gl::TextureType::_3D && baseImage->getDepth() <= 0)
     {
         return true;
     }
 
-    if (baseImage->getTarget() == GL_TEXTURE_3D && baseImage->getDepth() <= 0)
-    {
-        return true;
-    }
-
-    if (baseImage->getTarget() == GL_TEXTURE_2D_ARRAY && getLayerCount(getBaseLevel()) <= 0)
+    if (baseImage->getType() == gl::TextureType::_2DArray && getLayerCount(getBaseLevel()) <= 0)
     {
         return true;
     }
 
     return false;
 }
 
 gl::Error TextureD3D::ensureRenderTarget(const gl::Context *context)
@@ -577,17 +572,17 @@ gl::Error TextureD3D::ensureRenderTarget
         }
     }
 
     return gl::NoError();
 }
 
 bool TextureD3D::canCreateRenderTargetForImage(const gl::ImageIndex &index) const
 {
-    if (index.type == GL_TEXTURE_2D_MULTISAMPLE)
+    if (index.type == gl::TextureType::_2DMultisample)
         return true;
 
     ImageD3D *image = getImage(index);
     ASSERT(image);
     bool levelsComplete = (isImageComplete(index) && isImageComplete(getImageIndex(0, 0)));
     return (image->isRenderableFormat() && levelsComplete);
 }
 
@@ -648,16 +643,19 @@ void TextureD3D::syncState(const gl::Tex
 }
 
 gl::Error TextureD3D::releaseTexStorage(const gl::Context *context)
 {
     if (!mTexStorage)
     {
         return gl::NoError();
     }
+
+    onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
+
     auto err = mTexStorage->onDestroy(context);
     SafeDelete(mTexStorage);
     return err;
 }
 
 gl::Error TextureD3D::onDestroy(const gl::Context *context)
 {
     return releaseTexStorage(context);
@@ -666,21 +664,21 @@ gl::Error TextureD3D::onDestroy(const gl
 gl::Error TextureD3D::initializeContents(const gl::Context *context,
                                          const gl::ImageIndex &imageIndexIn)
 {
     gl::ImageIndex imageIndex = imageIndexIn;
 
     // Special case for D3D11 3D textures. We can't create render targets for individual layers of a
     // 3D texture, so force the clear to the entire mip. There shouldn't ever be a case where we
     // would lose existing data.
-    if (imageIndex.type == GL_TEXTURE_3D)
+    if (imageIndex.type == gl::TextureType::_3D)
     {
         imageIndex.layerIndex = gl::ImageIndex::ENTIRE_LEVEL;
     }
-    else if (imageIndex.type == GL_TEXTURE_2D_ARRAY &&
+    else if (imageIndex.type == gl::TextureType::_2DArray &&
              imageIndex.layerIndex == gl::ImageIndex::ENTIRE_LEVEL)
     {
         GLsizei layerCount = getLayerCount(imageIndex.mipIndex);
         for (imageIndex.layerIndex = 0; imageIndex.layerIndex < layerCount; ++imageIndex.layerIndex)
         {
             ANGLE_TRY(initializeContents(context, imageIndex));
         }
         return gl::NoError();
@@ -689,47 +687,51 @@ gl::Error TextureD3D::initializeContents
     // Force image clean.
     ImageD3D *image = getImage(imageIndex);
     if (image)
     {
         image->markClean();
     }
 
     // Fast path: can use a render target clear.
-    if (canCreateRenderTargetForImage(imageIndex))
+    // We don't use the fast path with the zero max lod workaround because it would introduce a race
+    // between the rendertarget and the staging images.
+    if (canCreateRenderTargetForImage(imageIndex) &&
+        !mRenderer->getWorkarounds().zeroMaxLodWorkaround)
     {
         ANGLE_TRY(ensureRenderTarget(context));
         ASSERT(mTexStorage);
         RenderTargetD3D *renderTarget = nullptr;
         ANGLE_TRY(mTexStorage->getRenderTarget(context, imageIndex, &renderTarget));
         ANGLE_TRY(mRenderer->initRenderTarget(renderTarget));
         return gl::NoError();
     }
 
     // Slow path: non-renderable texture or the texture levels aren't set up.
     const auto &formatInfo = gl::GetSizedInternalFormatInfo(image->getInternalFormat());
 
     size_t imageBytes = 0;
-    ANGLE_TRY_RESULT(formatInfo.computeRowPitch(image->getWidth(), 1, 0),
+    ANGLE_TRY_RESULT(formatInfo.computeRowPitch(formatInfo.type, image->getWidth(), 1, 0),
                      imageBytes);
     imageBytes *= image->getHeight() * image->getDepth();
 
-    gl::PixelUnpackState defaultUnpackState;
+    gl::PixelUnpackState zeroDataUnpackState;
+    zeroDataUnpackState.alignment = 1;
 
     angle::MemoryBuffer *zeroBuffer = nullptr;
     ANGLE_TRY(context->getZeroFilledBuffer(imageBytes, &zeroBuffer));
     if (shouldUseSetData(image))
     {
         ANGLE_TRY(mTexStorage->setData(context, imageIndex, image, nullptr, formatInfo.type,
-                                       defaultUnpackState, zeroBuffer->data()));
+                                       zeroDataUnpackState, zeroBuffer->data()));
     }
     else
     {
         gl::Box fullImageArea(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth());
-        ANGLE_TRY(image->loadData(context, fullImageArea, defaultUnpackState, formatInfo.type,
+        ANGLE_TRY(image->loadData(context, fullImageArea, zeroDataUnpackState, formatInfo.type,
                                   zeroBuffer->data(), false));
 
         // Force an update to the tex storage so we avoid problems with subImage and dirty regions.
         if (mTexStorage)
         {
             ANGLE_TRY(commitRegion(context, imageIndex, fullImageArea));
             image->markClean();
         }
@@ -773,17 +775,17 @@ ImageD3D *TextureD3D_2D::getImage(int le
     ASSERT(layer == 0);
     return mImageArray[level].get();
 }
 
 ImageD3D *TextureD3D_2D::getImage(const gl::ImageIndex &index) const
 {
     ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
     ASSERT(!index.hasLayer());
-    ASSERT(index.type == GL_TEXTURE_2D);
+    ASSERT(index.type == gl::TextureType::_2D);
     return mImageArray[index.mipIndex].get();
 }
 
 GLsizei TextureD3D_2D::getLayerCount(int level) const
 {
     ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
     return 1;
 }
@@ -818,368 +820,336 @@ bool TextureD3D_2D::isDepth(GLint level)
 }
 
 bool TextureD3D_2D::isSRGB(GLint level) const
 {
     return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).colorEncoding == GL_SRGB;
 }
 
 gl::Error TextureD3D_2D::setImage(const gl::Context *context,
-                                  GLenum target,
-                                  size_t imageLevel,
+                                  const gl::ImageIndex &index,
                                   GLenum internalFormat,
                                   const gl::Extents &size,
                                   GLenum format,
                                   GLenum type,
                                   const gl::PixelUnpackState &unpack,
                                   const uint8_t *pixels)
 {
-    ASSERT(target == GL_TEXTURE_2D && size.depth == 1);
+    ASSERT(index.target == gl::TextureTarget::_2D && size.depth == 1);
 
     const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
 
     bool fastUnpacked = false;
-    GLint level       = static_cast<GLint>(imageLevel);
-
-    ANGLE_TRY(redefineImage(context, level, internalFormatInfo.sizedInternalFormat, size, false));
-
-    gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+
+    ANGLE_TRY(redefineImage(context, index.mipIndex, internalFormatInfo.sizedInternalFormat, size,
+                            false));
 
     // Attempt a fast gpu copy of the pixel data to the surface
     gl::Buffer *unpackBuffer =
         context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
     if (isFastUnpackable(unpackBuffer, internalFormatInfo.sizedInternalFormat) &&
-        isLevelComplete(level))
+        isLevelComplete(index.mipIndex))
     {
         // Will try to create RT storage if it does not exist
         RenderTargetD3D *destRenderTarget = nullptr;
         ANGLE_TRY(getRenderTarget(context, index, &destRenderTarget));
 
-        gl::Box destArea(0, 0, 0, getWidth(level), getHeight(level), 1);
+        gl::Box destArea(0, 0, 0, getWidth(index.mipIndex), getHeight(index.mipIndex), 1);
 
         ANGLE_TRY(fastUnpackPixels(context, unpack, pixels, destArea,
                                    internalFormatInfo.sizedInternalFormat, type, destRenderTarget));
 
         // Ensure we don't overwrite our newly initialized data
-        mImageArray[level]->markClean();
+        mImageArray[index.mipIndex]->markClean();
 
         fastUnpacked = true;
     }
 
     if (!fastUnpacked)
     {
         ANGLE_TRY(setImageImpl(context, index, type, unpack, pixels, 0));
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2D::setSubImage(const gl::Context *context,
-                                     GLenum target,
-                                     size_t imageLevel,
+                                     const gl::ImageIndex &index,
                                      const gl::Box &area,
                                      GLenum format,
                                      GLenum type,
                                      const gl::PixelUnpackState &unpack,
                                      const uint8_t *pixels)
 {
-    ASSERT(target == GL_TEXTURE_2D && area.depth == 1 && area.z == 0);
-
-    GLint level          = static_cast<GLint>(imageLevel);
-    gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+    ASSERT(index.target == gl::TextureTarget::_2D && area.depth == 1 && area.z == 0);
 
     gl::Buffer *unpackBuffer =
         context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
-    if (isFastUnpackable(unpackBuffer, getInternalFormat(level)) && isLevelComplete(level))
+    GLenum mipFormat = getInternalFormat(index.mipIndex);
+    if (isFastUnpackable(unpackBuffer, mipFormat) && isLevelComplete(index.mipIndex))
     {
         RenderTargetD3D *renderTarget = nullptr;
         ANGLE_TRY(getRenderTarget(context, index, &renderTarget));
-        ASSERT(!mImageArray[level]->isDirty());
-
-        return fastUnpackPixels(context, unpack, pixels, area, getInternalFormat(level), type,
-                                renderTarget);
+        ASSERT(!mImageArray[index.mipIndex]->isDirty());
+
+        return fastUnpackPixels(context, unpack, pixels, area, mipFormat, type, renderTarget);
     }
     else
     {
         return TextureD3D::subImage(context, index, area, format, type, unpack, pixels, 0);
     }
 }
 
 gl::Error TextureD3D_2D::setCompressedImage(const gl::Context *context,
-                                            GLenum target,
-                                            size_t imageLevel,
+                                            const gl::ImageIndex &index,
                                             GLenum internalFormat,
                                             const gl::Extents &size,
                                             const gl::PixelUnpackState &unpack,
                                             size_t imageSize,
                                             const uint8_t *pixels)
 {
-    ASSERT(target == GL_TEXTURE_2D && size.depth == 1);
-    GLint level = static_cast<GLint>(imageLevel);
+    ASSERT(index.target == gl::TextureTarget::_2D && size.depth == 1);
 
     // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
-    ANGLE_TRY(redefineImage(context, level, internalFormat, size, false));
-
-    return setCompressedImageImpl(context, gl::ImageIndex::Make2D(level), unpack, pixels, 0);
+    ANGLE_TRY(redefineImage(context, index.mipIndex, internalFormat, size, false));
+
+    return setCompressedImageImpl(context, index, unpack, pixels, 0);
 }
 
 gl::Error TextureD3D_2D::setCompressedSubImage(const gl::Context *context,
-                                               GLenum target,
-                                               size_t level,
+                                               const gl::ImageIndex &index,
                                                const gl::Box &area,
                                                GLenum format,
                                                const gl::PixelUnpackState &unpack,
                                                size_t imageSize,
                                                const uint8_t *pixels)
 {
-    ASSERT(target == GL_TEXTURE_2D && area.depth == 1 && area.z == 0);
-
-    gl::ImageIndex index = gl::ImageIndex::Make2D(static_cast<GLint>(level));
+    ASSERT(index.target == gl::TextureTarget::_2D && area.depth == 1 && area.z == 0);
     ANGLE_TRY(TextureD3D::subImageCompressed(context, index, area, format, unpack, pixels, 0));
 
     return commitRegion(context, index, area);
 }
 
 gl::Error TextureD3D_2D::copyImage(const gl::Context *context,
-                                   GLenum target,
-                                   size_t imageLevel,
+                                   const gl::ImageIndex &index,
                                    const gl::Rectangle &origSourceArea,
                                    GLenum internalFormat,
-                                   const gl::Framebuffer *source)
+                                   gl::Framebuffer *source)
 {
-    ASSERT(target == GL_TEXTURE_2D);
-
-    GLint level = static_cast<GLint>(imageLevel);
+    ASSERT(index.target == gl::TextureTarget::_2D);
+
     const gl::InternalFormat &internalFormatInfo =
         gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE);
     gl::Extents sourceExtents(origSourceArea.width, origSourceArea.height, 1);
-    ANGLE_TRY(redefineImage(context, level, internalFormatInfo.sizedInternalFormat, sourceExtents,
-                            false));
+    ANGLE_TRY(redefineImage(context, index.mipIndex, internalFormatInfo.sizedInternalFormat,
+                            sourceExtents, false));
 
     gl::Extents fbSize = source->getReadColorbuffer()->getSize();
 
     // Does the read area extend beyond the framebuffer?
     bool outside = origSourceArea.x < 0 || origSourceArea.y < 0 ||
                    origSourceArea.x + origSourceArea.width > fbSize.width ||
                    origSourceArea.y + origSourceArea.height > fbSize.height;
 
-    // In WebGL mode we need to zero the texture outside the framebuffer.
-    // If we have robust resource init, it was already zeroed by redefineImage() above, otherwise
-    // zero it explicitly.
-    // TODO(fjhenigman): When robust resource is fully implemented look into making it a
-    // prerequisite for WebGL and deleting this code.
+    // WebGL requires that pixels that would be outside the framebuffer are treated as zero values,
+    // so clear the mip level to 0 prior to making the copy if any pixel would be sampled outside.
+    // Same thing for robust resource init.
     if (outside &&
         (context->getExtensions().webglCompatibility || context->isRobustResourceInitEnabled()))
     {
-        angle::MemoryBuffer *zero;
-        ANGLE_TRY(context->getZeroFilledBuffer(
-            origSourceArea.width * origSourceArea.height * internalFormatInfo.pixelBytes, &zero));
-        gl::PixelUnpackState unpack;
-        unpack.alignment = 1;
-        ANGLE_TRY(setImage(context, target, imageLevel, internalFormat, sourceExtents,
-                           internalFormatInfo.format, internalFormatInfo.type, unpack,
-                           zero->data()));
+        ANGLE_TRY(initializeContents(context, index));
     }
 
     gl::Rectangle sourceArea;
     if (!ClipRectangle(origSourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height),
                        &sourceArea))
     {
         // Empty source area, nothing to do.
         return gl::NoError();
     }
 
-    gl::ImageIndex index = gl::ImageIndex::Make2D(level);
     gl::Offset destOffset(sourceArea.x - origSourceArea.x, sourceArea.y - origSourceArea.y, 0);
 
     // If the zero max LOD workaround is active, then we can't sample from individual layers of the framebuffer in shaders,
     // so we should use the non-rendering copy path.
     if (!canCreateRenderTargetForImage(index) || mRenderer->getWorkarounds().zeroMaxLodWorkaround)
     {
-        ANGLE_TRY(mImageArray[level]->copyFromFramebuffer(context, destOffset, sourceArea, source));
+        ANGLE_TRY(mImageArray[index.mipIndex]->copyFromFramebuffer(context, destOffset, sourceArea,
+                                                                   source));
         mDirtyImages = true;
     }
     else
     {
         ANGLE_TRY(ensureRenderTarget(context));
 
-        if (sourceArea.width != 0 && sourceArea.height != 0 && isValidLevel(level))
+        if (sourceArea.width != 0 && sourceArea.height != 0 && isValidLevel(index.mipIndex))
         {
-            ANGLE_TRY(updateStorageLevel(context, level));
+            ANGLE_TRY(updateStorageLevel(context, index.mipIndex));
             ANGLE_TRY(mRenderer->copyImage2D(context, source, sourceArea, internalFormat,
-                                             destOffset, mTexStorage, level));
+                                             destOffset, mTexStorage, index.mipIndex));
         }
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2D::copySubImage(const gl::Context *context,
-                                      GLenum target,
-                                      size_t imageLevel,
+                                      const gl::ImageIndex &index,
                                       const gl::Offset &origDestOffset,
                                       const gl::Rectangle &origSourceArea,
-                                      const gl::Framebuffer *source)
+                                      gl::Framebuffer *source)
 {
-    ASSERT(target == GL_TEXTURE_2D && origDestOffset.z == 0);
+    ASSERT(index.target == gl::TextureTarget::_2D && origDestOffset.z == 0);
 
     gl::Extents fbSize = source->getReadColorbuffer()->getSize();
     gl::Rectangle sourceArea;
     if (!ClipRectangle(origSourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height),
                        &sourceArea))
     {
         return gl::NoError();
     }
     const gl::Offset destOffset(origDestOffset.x + sourceArea.x - origSourceArea.x,
                                 origDestOffset.y + sourceArea.y - origSourceArea.y, 0);
 
     // can only make our texture storage to a render target if level 0 is defined (with a width & height) and
     // the current level we're copying to is defined (with appropriate format, width & height)
 
-    GLint level          = static_cast<GLint>(imageLevel);
-    gl::ImageIndex index = gl::ImageIndex::Make2D(level);
-
     // If the zero max LOD workaround is active, then we can't sample from individual layers of the framebuffer in shaders,
     // so we should use the non-rendering copy path.
     if (!canCreateRenderTargetForImage(index) || mRenderer->getWorkarounds().zeroMaxLodWorkaround)
     {
-        ANGLE_TRY(mImageArray[level]->copyFromFramebuffer(context, destOffset, sourceArea, source));
+        ANGLE_TRY(mImageArray[index.mipIndex]->copyFromFramebuffer(context, destOffset, sourceArea,
+                                                                   source));
         mDirtyImages = true;
     }
     else
     {
         ANGLE_TRY(ensureRenderTarget(context));
 
-        if (isValidLevel(level))
+        if (isValidLevel(index.mipIndex))
         {
-            ANGLE_TRY(updateStorageLevel(context, level));
+            ANGLE_TRY(updateStorageLevel(context, index.mipIndex));
             ANGLE_TRY(mRenderer->copyImage2D(context, source, sourceArea,
                                              gl::GetUnsizedFormat(getBaseLevelInternalFormat()),
-                                             destOffset, mTexStorage, level));
+                                             destOffset, mTexStorage, index.mipIndex));
         }
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2D::copyTexture(const gl::Context *context,
-                                     GLenum target,
-                                     size_t level,
+                                     const gl::ImageIndex &index,
                                      GLenum internalFormat,
                                      GLenum type,
                                      size_t sourceLevel,
                                      bool unpackFlipY,
                                      bool unpackPremultiplyAlpha,
                                      bool unpackUnmultiplyAlpha,
                                      const gl::Texture *source)
 {
-    ASSERT(target == GL_TEXTURE_2D);
-
-    GLenum sourceTarget = source->getTarget();
-
-    GLint destLevel = static_cast<GLint>(level);
+    ASSERT(index.target == gl::TextureTarget::_2D);
+
+    gl::TextureType sourceType = source->getType();
 
     const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
-    gl::Extents size(static_cast<int>(source->getWidth(sourceTarget, sourceLevel)),
-                     static_cast<int>(source->getHeight(sourceTarget, sourceLevel)), 1);
-    ANGLE_TRY(
-        redefineImage(context, destLevel, internalFormatInfo.sizedInternalFormat, size, false));
+    gl::Extents size(
+        static_cast<int>(source->getWidth(NonCubeTextureTypeToTarget(sourceType), sourceLevel)),
+        static_cast<int>(source->getHeight(NonCubeTextureTypeToTarget(sourceType), sourceLevel)),
+        1);
+    ANGLE_TRY(redefineImage(context, index.mipIndex, internalFormatInfo.sizedInternalFormat, size,
+                            false));
 
     gl::Rectangle sourceRect(0, 0, size.width, size.height);
     gl::Offset destOffset(0, 0, 0);
 
-    if (!isSRGB(destLevel) && canCreateRenderTargetForImage(gl::ImageIndex::Make2D(destLevel)))
+    if (!isSRGB(index.mipIndex) && canCreateRenderTargetForImage(index))
     {
         ANGLE_TRY(ensureRenderTarget(context));
-        ASSERT(isValidLevel(destLevel));
-        ANGLE_TRY(updateStorageLevel(context, destLevel));
+        ASSERT(isValidLevel(index.mipIndex));
+        ANGLE_TRY(updateStorageLevel(context, index.mipIndex));
 
         ANGLE_TRY(mRenderer->copyTexture(
             context, source, static_cast<GLint>(sourceLevel), sourceRect, internalFormatInfo.format,
-            internalFormatInfo.type, destOffset, mTexStorage, target, destLevel, unpackFlipY,
-            unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+            internalFormatInfo.type, destOffset, mTexStorage, index.target, index.mipIndex,
+            unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
     }
     else
     {
         gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(static_cast<GLint>(sourceLevel));
         TextureD3D *sourceD3D           = GetImplAs<TextureD3D>(source);
         ImageD3D *sourceImage           = nullptr;
         ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage));
 
-        gl::ImageIndex destImageIndex = gl::ImageIndex::Make2D(static_cast<GLint>(destLevel));
         ImageD3D *destImage           = nullptr;
-        ANGLE_TRY(getImageAndSyncFromStorage(context, destImageIndex, &destImage));
+        ANGLE_TRY(getImageAndSyncFromStorage(context, index, &destImage));
 
         ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceRect, destOffset,
                                        unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
 
         mDirtyImages = true;
 
         gl::Box destRegion(destOffset, size);
-        ANGLE_TRY(commitRegion(context, destImageIndex, destRegion));
+        ANGLE_TRY(commitRegion(context, index, destRegion));
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2D::copySubTexture(const gl::Context *context,
-                                        GLenum target,
-                                        size_t level,
+                                        const gl::ImageIndex &index,
                                         const gl::Offset &destOffset,
                                         size_t sourceLevel,
                                         const gl::Rectangle &sourceArea,
                                         bool unpackFlipY,
                                         bool unpackPremultiplyAlpha,
                                         bool unpackUnmultiplyAlpha,
                                         const gl::Texture *source)
 {
-    ASSERT(target == GL_TEXTURE_2D);
-
-    GLint destLevel = static_cast<GLint>(level);
-
-    if (!isSRGB(destLevel) && canCreateRenderTargetForImage(gl::ImageIndex::Make2D(destLevel)))
+    ASSERT(index.target == gl::TextureTarget::_2D);
+
+    if (!isSRGB(index.mipIndex) && canCreateRenderTargetForImage(index))
     {
         ANGLE_TRY(ensureRenderTarget(context));
-        ASSERT(isValidLevel(destLevel));
-        ANGLE_TRY(updateStorageLevel(context, destLevel));
+        ASSERT(isValidLevel(index.mipIndex));
+        ANGLE_TRY(updateStorageLevel(context, index.mipIndex));
 
         const gl::InternalFormat &internalFormatInfo =
-            gl::GetSizedInternalFormatInfo(getInternalFormat(destLevel));
+            gl::GetSizedInternalFormatInfo(getInternalFormat(index.mipIndex));
         ANGLE_TRY(mRenderer->copyTexture(
             context, source, static_cast<GLint>(sourceLevel), sourceArea, internalFormatInfo.format,
-            internalFormatInfo.type, destOffset, mTexStorage, target, destLevel, unpackFlipY,
-            unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+            internalFormatInfo.type, destOffset, mTexStorage, index.target, index.mipIndex,
+            unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
     }
     else
     {
         gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(static_cast<GLint>(sourceLevel));
         TextureD3D *sourceD3D           = GetImplAs<TextureD3D>(source);
         ImageD3D *sourceImage           = nullptr;
         ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage));
 
-        gl::ImageIndex destImageIndex = gl::ImageIndex::Make2D(static_cast<GLint>(destLevel));
         ImageD3D *destImage           = nullptr;
-        ANGLE_TRY(getImageAndSyncFromStorage(context, destImageIndex, &destImage));
+        ANGLE_TRY(getImageAndSyncFromStorage(context, index, &destImage));
 
         ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceArea, destOffset,
                                        unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
 
         mDirtyImages = true;
 
         gl::Box destRegion(destOffset.x, destOffset.y, 0, sourceArea.width, sourceArea.height, 1);
-        ANGLE_TRY(commitRegion(context, destImageIndex, destRegion));
+        ANGLE_TRY(commitRegion(context, index, destRegion));
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2D::copyCompressedTexture(const gl::Context *context,
                                                const gl::Texture *source)
 {
-    GLenum sourceTarget = source->getTarget();
+    gl::TextureTarget sourceTarget = NonCubeTextureTypeToTarget(source->getType());
     GLint sourceLevel   = 0;
 
     GLint destLevel = 0;
 
     GLenum sizedInternalFormat =
         source->getFormat(sourceTarget, sourceLevel).info->sizedInternalFormat;
     gl::Extents size(static_cast<int>(source->getWidth(sourceTarget, sourceLevel)),
                      static_cast<int>(source->getHeight(sourceTarget, sourceLevel)), 1);
@@ -1190,22 +1160,22 @@ gl::Error TextureD3D_2D::copyCompressedT
 
     ANGLE_TRY(
         mRenderer->copyCompressedTexture(context, source, sourceLevel, mTexStorage, destLevel));
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2D::setStorage(const gl::Context *context,
-                                    GLenum target,
+                                    gl::TextureType type,
                                     size_t levels,
                                     GLenum internalFormat,
                                     const gl::Extents &size)
 {
-    ASSERT(GL_TEXTURE_2D && size.depth == 1);
+    ASSERT(type == gl::TextureType::_2D && size.depth == 1);
 
     for (size_t level = 0; level < levels; level++)
     {
         gl::Extents levelSize(std::max(1, size.width >> level),
                               std::max(1, size.height >> level),
                               1);
         ANGLE_TRY(redefineImage(context, level, internalFormat, levelSize, true));
     }
@@ -1244,16 +1214,18 @@ gl::Error TextureD3D_2D::bindTexImage(co
     ASSERT(surfaceD3D);
 
     mTexStorage = mRenderer->createTextureStorage2D(surfaceD3D->getSwapChain());
     mEGLImageTarget = false;
 
     mDirtyImages = false;
     mImageArray[0]->markClean();
 
+    mTexStorage->setSubject(this);
+
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2D::releaseTexImage(const gl::Context *context)
 {
     if (mTexStorage)
     {
         ANGLE_TRY(releaseTexStorage(context));
@@ -1263,17 +1235,17 @@ gl::Error TextureD3D_2D::releaseTexImage
     {
         ANGLE_TRY(redefineImage(context, i, GL_NONE, gl::Extents(0, 0, 1), true));
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2D::setEGLImageTarget(const gl::Context *context,
-                                           GLenum target,
+                                           gl::TextureType type,
                                            egl::Image *image)
 {
     EGLImageD3D *eglImaged3d = GetImplAs<EGLImageD3D>(image);
 
     // Set the properties of the base mip level from the EGL image
     const auto &format = image->getFormat();
     gl::Extents size(static_cast<int>(image->getWidth()), static_cast<int>(image->getHeight()), 1);
     ANGLE_TRY(redefineImage(context, 0, format.info->sizedInternalFormat, size, true));
@@ -1432,16 +1404,17 @@ gl::Error TextureD3D_2D::createCompleteS
         {
             hintLevelZeroOnly = !(mImageArray[level]->isDirty() && isLevelComplete(level));
         }
     }
 
     // TODO(geofflang): Determine if the texture creation succeeded
     outStorage->reset(mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height,
                                                         levels, hintLevelZeroOnly));
+    (*outStorage)->setSubject(this);
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2D::setCompleteTexStorage(const gl::Context *context,
                                                TextureStorage *newCompleteTexStorage)
 {
     if (newCompleteTexStorage && newCompleteTexStorage->isManaged())
@@ -1451,16 +1424,18 @@ gl::Error TextureD3D_2D::setCompleteTexS
             ANGLE_TRY(
                 mImageArray[level]->setManagedSurface2D(context, newCompleteTexStorage, level));
         }
     }
 
     ANGLE_TRY(releaseTexStorage(context));
     mTexStorage = newCompleteTexStorage;
 
+    mTexStorage->setSubject(this);
+
     mDirtyImages = true;
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2D::updateStorage(const gl::Context *context)
 {
     if (!mDirtyImages)
@@ -1505,17 +1480,17 @@ gl::Error TextureD3D_2D::redefineImage(c
 {
     ASSERT(size.depth == 1);
 
     // If there currently is a corresponding storage texture image, it has these parameters
     const int storageWidth     = std::max(1, getLevelZeroWidth() >> level);
     const int storageHeight    = std::max(1, getLevelZeroHeight() >> level);
     const GLenum storageFormat = getBaseLevelInternalFormat();
 
-    mImageArray[level]->redefine(GL_TEXTURE_2D, internalformat, size, forceRelease);
+    mImageArray[level]->redefine(gl::TextureType::_2D, internalformat, size, forceRelease);
     mDirtyImages = mDirtyImages || mImageArray[level]->isDirty();
 
     if (mTexStorage)
     {
         const size_t storageLevels = mTexStorage->getLevelCount();
 
         // If the storage was from an EGL image, copy it back into local images to preserve it
         // while orphaning
@@ -1548,17 +1523,17 @@ gl::ImageIndexIterator TextureD3D_2D::im
 gl::ImageIndex TextureD3D_2D::getImageIndex(GLint mip, GLint /*layer*/) const
 {
     // "layer" does not apply to 2D Textures.
     return gl::ImageIndex::Make2D(mip);
 }
 
 bool TextureD3D_2D::isValidIndex(const gl::ImageIndex &index) const
 {
-    return (mTexStorage && index.type == GL_TEXTURE_2D && index.mipIndex >= 0 &&
+    return (mTexStorage && index.type == gl::TextureType::_2D && index.mipIndex >= 0 &&
             index.mipIndex < mTexStorage->getLevelCount());
 }
 
 void TextureD3D_2D::markAllImagesDirty()
 {
     for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
     {
         mImageArray[i]->markDirty();
@@ -1602,17 +1577,17 @@ ImageD3D *TextureD3D_Cube::getImage(int 
     ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
     ASSERT(layer >= 0 && layer < 6);
     return mImageArray[layer][level].get();
 }
 
 ImageD3D *TextureD3D_Cube::getImage(const gl::ImageIndex &index) const
 {
     ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
-    ASSERT(gl::IsCubeMapTextureTarget(index.target));
+    ASSERT(gl::TextureTargetToType(index.target) == gl::TextureType::CubeMap);
     return mImageArray[index.cubeMapFaceIndex()][index.mipIndex].get();
 }
 
 GLsizei TextureD3D_Cube::getLayerCount(int level) const
 {
     ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
     return 6;
 }
@@ -1631,360 +1606,323 @@ bool TextureD3D_Cube::isDepth(GLint leve
 }
 
 bool TextureD3D_Cube::isSRGB(GLint level, GLint layer) const
 {
     return gl::GetSizedInternalFormatInfo(getInternalFormat(level, layer)).colorEncoding == GL_SRGB;
 }
 
 gl::Error TextureD3D_Cube::setEGLImageTarget(const gl::Context *context,
-                                             GLenum target,
+                                             gl::TextureType type,
                                              egl::Image *image)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_Cube::setImage(const gl::Context *context,
-                                    GLenum target,
-                                    size_t level,
+                                    const gl::ImageIndex &index,
                                     GLenum internalFormat,
                                     const gl::Extents &size,
                                     GLenum format,
                                     GLenum type,
                                     const gl::PixelUnpackState &unpack,
                                     const uint8_t *pixels)
 {
     ASSERT(size.depth == 1);
 
     const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
-    gl::ImageIndex index       = gl::ImageIndex::MakeCube(target, static_cast<GLint>(level));
-
-    ANGLE_TRY(redefineImage(context, index.cubeMapFaceIndex(), static_cast<GLint>(level),
+    ANGLE_TRY(redefineImage(context, index.cubeMapFaceIndex(), index.mipIndex,
                             internalFormatInfo.sizedInternalFormat, size, false));
 
     return setImageImpl(context, index, type, unpack, pixels, 0);
 }
 
 gl::Error TextureD3D_Cube::setSubImage(const gl::Context *context,
-                                       GLenum target,
-                                       size_t level,
+                                       const gl::ImageIndex &index,
                                        const gl::Box &area,
                                        GLenum format,
                                        GLenum type,
                                        const gl::PixelUnpackState &unpack,
                                        const uint8_t *pixels)
 {
     ASSERT(area.depth == 1 && area.z == 0);
-
-    gl::ImageIndex index = gl::ImageIndex::MakeCube(target, static_cast<GLint>(level));
     return TextureD3D::subImage(context, index, area, format, type, unpack, pixels, 0);
 }
 
 gl::Error TextureD3D_Cube::setCompressedImage(const gl::Context *context,
-                                              GLenum target,
-                                              size_t level,
+                                              const gl::ImageIndex &index,
                                               GLenum internalFormat,
                                               const gl::Extents &size,
                                               const gl::PixelUnpackState &unpack,
                                               size_t imageSize,
                                               const uint8_t *pixels)
 {
     ASSERT(size.depth == 1);
 
     // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
-    size_t faceIndex = gl::CubeMapTextureTargetToLayerIndex(target);
-
-    ANGLE_TRY(redefineImage(context, static_cast<int>(faceIndex), static_cast<GLint>(level),
-                            internalFormat, size, false));
-
-    gl::ImageIndex index = gl::ImageIndex::MakeCube(target, static_cast<GLint>(level));
+    ANGLE_TRY(redefineImage(context, index.cubeMapFaceIndex(), index.mipIndex, internalFormat, size,
+                            false));
+
     return setCompressedImageImpl(context, index, unpack, pixels, 0);
 }
 
 gl::Error TextureD3D_Cube::setCompressedSubImage(const gl::Context *context,
-                                                 GLenum target,
-                                                 size_t level,
+                                                 const gl::ImageIndex &index,
                                                  const gl::Box &area,
                                                  GLenum format,
                                                  const gl::PixelUnpackState &unpack,
                                                  size_t imageSize,
                                                  const uint8_t *pixels)
 {
     ASSERT(area.depth == 1 && area.z == 0);
 
-    gl::ImageIndex index = gl::ImageIndex::MakeCube(target, static_cast<GLint>(level));
-
     ANGLE_TRY(TextureD3D::subImageCompressed(context, index, area, format, unpack, pixels, 0));
     return commitRegion(context, index, area);
 }
 
 gl::Error TextureD3D_Cube::copyImage(const gl::Context *context,
-                                     GLenum target,
-                                     size_t imageLevel,
+                                     const gl::ImageIndex &index,
                                      const gl::Rectangle &origSourceArea,
                                      GLenum internalFormat,
-                                     const gl::Framebuffer *source)
+                                     gl::Framebuffer *source)
 {
-    int faceIndex              = static_cast<int>(gl::CubeMapTextureTargetToLayerIndex(target));
+    GLint faceIndex = index.cubeMapFaceIndex();
     const gl::InternalFormat &internalFormatInfo =
         gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE);
 
-    GLint level = static_cast<GLint>(imageLevel);
-
     gl::Extents size(origSourceArea.width, origSourceArea.height, 1);
-    ANGLE_TRY(redefineImage(context, static_cast<int>(faceIndex), level,
+    ANGLE_TRY(redefineImage(context, faceIndex, index.mipIndex,
                             internalFormatInfo.sizedInternalFormat, size, false));
 
     gl::Extents fbSize = source->getReadColorbuffer()->getSize();
 
     // Does the read area extend beyond the framebuffer?
     bool outside = origSourceArea.x < 0 || origSourceArea.y < 0 ||
                    origSourceArea.x + origSourceArea.width > fbSize.width ||
                    origSourceArea.y + origSourceArea.height > fbSize.height;
 
-    // In WebGL mode we need to zero the texture outside the framebuffer.
-    // If we have robust resource init, it was already zeroed by redefineImage() above, otherwise
-    // zero it explicitly.
-    // TODO(fjhenigman): When robust resource is fully implemented look into making it a
-    // prerequisite for WebGL and deleting this code.
-    if (outside && context->getExtensions().webglCompatibility &&
-        !context->isRobustResourceInitEnabled())
+    // WebGL requires that pixels that would be outside the framebuffer are treated as zero values,
+    // so clear the mip level to 0 prior to making the copy if any pixel would be sampled outside.
+    // Same thing for robust resource init.
+    if (outside &&
+        (context->getExtensions().webglCompatibility || context->isRobustResourceInitEnabled()))
     {
-        angle::MemoryBuffer *zero;
-        ANGLE_TRY(context->getZeroFilledBuffer(
-            origSourceArea.width * origSourceArea.height * internalFormatInfo.pixelBytes, &zero));
-        gl::PixelUnpackState unpack;
-        unpack.alignment = 1;
-        ANGLE_TRY(setImage(context, target, imageLevel, internalFormat, size,
-                           internalFormatInfo.format, internalFormatInfo.type, unpack,
-                           zero->data()));
+        ANGLE_TRY(initializeContents(context, index));
     }
 
     gl::Rectangle sourceArea;
     if (!ClipRectangle(origSourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height),
                        &sourceArea))
     {
         // Empty source area, nothing to do.
         return gl::NoError();
     }
 
-    gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
     gl::Offset destOffset(sourceArea.x - origSourceArea.x, sourceArea.y - origSourceArea.y, 0);
 
     // If the zero max LOD workaround is active, then we can't sample from individual layers of the framebuffer in shaders,
     // so we should use the non-rendering copy path.
     if (!canCreateRenderTargetForImage(index) || mRenderer->getWorkarounds().zeroMaxLodWorkaround)
     {
-        ANGLE_TRY(mImageArray[faceIndex][level]->copyFromFramebuffer(context, destOffset,
-                                                                     sourceArea, source));
+        ANGLE_TRY(mImageArray[faceIndex][index.mipIndex]->copyFromFramebuffer(context, destOffset,
+                                                                              sourceArea, source));
         mDirtyImages = true;
     }
     else
     {
         ANGLE_TRY(ensureRenderTarget(context));
 
         ASSERT(size.width == size.height);
 
-        if (size.width > 0 && isValidFaceLevel(faceIndex, level))
+        if (size.width > 0 && isValidFaceLevel(faceIndex, index.mipIndex))
         {
-            ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, level));
+            ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, index.mipIndex));
             ANGLE_TRY(mRenderer->copyImageCube(context, source, sourceArea, internalFormat,
-                                               destOffset, mTexStorage, target, level));
+                                               destOffset, mTexStorage, index.target,
+                                               index.mipIndex));
         }
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_Cube::copySubImage(const gl::Context *context,
-                                        GLenum target,
-                                        size_t imageLevel,
+                                        const gl::ImageIndex &index,
                                         const gl::Offset &origDestOffset,
                                         const gl::Rectangle &origSourceArea,
-                                        const gl::Framebuffer *source)
+                                        gl::Framebuffer *source)
 {
     gl::Extents fbSize = source->getReadColorbuffer()->getSize();
     gl::Rectangle sourceArea;
     if (!ClipRectangle(origSourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height),
                        &sourceArea))
     {
         return gl::NoError();
     }
     const gl::Offset destOffset(origDestOffset.x + sourceArea.x - origSourceArea.x,
                                 origDestOffset.y + sourceArea.y - origSourceArea.y, 0);
 
-    int faceIndex = static_cast<int>(gl::CubeMapTextureTargetToLayerIndex(target));
-
-    GLint level          = static_cast<GLint>(imageLevel);
-    gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
+    GLint faceIndex = index.cubeMapFaceIndex();
 
     // If the zero max LOD workaround is active, then we can't sample from individual layers of the framebuffer in shaders,
     // so we should use the non-rendering copy path.
     if (!canCreateRenderTargetForImage(index) || mRenderer->getWorkarounds().zeroMaxLodWorkaround)
     {
-        ANGLE_TRY(mImageArray[faceIndex][level]->copyFromFramebuffer(context, destOffset,
-                                                                     sourceArea, source));
+        ANGLE_TRY(mImageArray[faceIndex][index.mipIndex]->copyFromFramebuffer(context, destOffset,
+                                                                              sourceArea, source));
         mDirtyImages = true;
     }
     else
     {
         ANGLE_TRY(ensureRenderTarget(context));
-        if (isValidFaceLevel(faceIndex, level))
+        if (isValidFaceLevel(faceIndex, index.mipIndex))
         {
-            ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, level));
-            ANGLE_TRY(mRenderer->copyImageCube(context, source, sourceArea,
-                                               gl::GetUnsizedFormat(getBaseLevelInternalFormat()),
-                                               destOffset, mTexStorage, target, level));
+            ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, index.mipIndex));
+            ANGLE_TRY(mRenderer->copyImageCube(
+                context, source, sourceArea, gl::GetUnsizedFormat(getBaseLevelInternalFormat()),
+                destOffset, mTexStorage, index.target, index.mipIndex));
         }
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_Cube::copyTexture(const gl::Context *context,
-                                       GLenum target,
-                                       size_t level,
+                                       const gl::ImageIndex &index,
                                        GLenum internalFormat,
                                        GLenum type,
                                        size_t sourceLevel,
                                        bool unpackFlipY,
                                        bool unpackPremultiplyAlpha,
                                        bool unpackUnmultiplyAlpha,
                                        const gl::Texture *source)
 {
-    ASSERT(gl::IsCubeMapTextureTarget(target));
-
-    GLenum sourceTarget = source->getTarget();
-
-    GLint destLevel = static_cast<GLint>(level);
-    int faceIndex   = static_cast<int>(gl::CubeMapTextureTargetToLayerIndex(target));
+    ASSERT(gl::TextureTargetToType(index.target) == gl::TextureType::CubeMap);
+
+    gl::TextureTarget sourceTarget = NonCubeTextureTypeToTarget(source->getType());
+
+    GLint faceIndex = index.cubeMapFaceIndex();
 
     const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
     gl::Extents size(static_cast<int>(source->getWidth(sourceTarget, sourceLevel)),
                      static_cast<int>(source->getHeight(sourceTarget, sourceLevel)), 1);
-    ANGLE_TRY(redefineImage(context, faceIndex, destLevel, internalFormatInfo.sizedInternalFormat,
-                            size, false));
+    ANGLE_TRY(redefineImage(context, faceIndex, index.mipIndex,
+                            internalFormatInfo.sizedInternalFormat, size, false));
 
     gl::Rectangle sourceRect(0, 0, size.width, size.height);
     gl::Offset destOffset(0, 0, 0);
 
-    if (!isSRGB(destLevel, faceIndex) &&
-        canCreateRenderTargetForImage(gl::ImageIndex::MakeCube(target, destLevel)))
+    if (!isSRGB(index.mipIndex, faceIndex) && canCreateRenderTargetForImage(index))
     {
         ANGLE_TRY(ensureRenderTarget(context));
-        ASSERT(isValidFaceLevel(faceIndex, destLevel));
-        ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, destLevel));
+        ASSERT(isValidFaceLevel(faceIndex, index.mipIndex));
+        ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, index.mipIndex));
 
         ANGLE_TRY(mRenderer->copyTexture(
             context, source, static_cast<GLint>(sourceLevel), sourceRect, internalFormatInfo.format,
-            internalFormatInfo.type, destOffset, mTexStorage, target, destLevel, unpackFlipY,
-            unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+            internalFormatInfo.type, destOffset, mTexStorage, index.target, index.mipIndex,
+            unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
     }
     else
     {
         gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(static_cast<GLint>(sourceLevel));
         TextureD3D *sourceD3D           = GetImplAs<TextureD3D>(source);
         ImageD3D *sourceImage           = nullptr;
         ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage));
 
-        gl::ImageIndex destImageIndex =
-            gl::ImageIndex::MakeCube(target, static_cast<GLint>(destLevel));
         ImageD3D *destImage = nullptr;
-        ANGLE_TRY(getImageAndSyncFromStorage(context, destImageIndex, &destImage));
+        ANGLE_TRY(getImageAndSyncFromStorage(context, index, &destImage));
 
         ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceRect, destOffset,
                                        unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
 
         mDirtyImages = true;
 
         gl::Box destRegion(destOffset, size);
-        ANGLE_TRY(commitRegion(context, destImageIndex, destRegion));
+        ANGLE_TRY(commitRegion(context, index, destRegion));
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_Cube::copySubTexture(const gl::Context *context,
-                                          GLenum target,
-                                          size_t level,
+                                          const gl::ImageIndex &index,
                                           const gl::Offset &destOffset,
                                           size_t sourceLevel,
                                           const gl::Rectangle &sourceArea,
                                           bool unpackFlipY,
                                           bool unpackPremultiplyAlpha,
                                           bool unpackUnmultiplyAlpha,
                                           const gl::Texture *source)
 {
-    ASSERT(gl::IsCubeMapTextureTarget(target));
-
-    GLint destLevel = static_cast<GLint>(level);
-    int faceIndex   = static_cast<int>(gl::CubeMapTextureTargetToLayerIndex(target));
-
-    if (!isSRGB(destLevel, faceIndex) &&
-        canCreateRenderTargetForImage(gl::ImageIndex::MakeCube(target, destLevel)))
+    ASSERT(gl::TextureTargetToType(index.target) == gl::TextureType::CubeMap);
+
+    GLint faceIndex = index.cubeMapFaceIndex();
+
+    if (!isSRGB(index.mipIndex, faceIndex) && canCreateRenderTargetForImage(index))
     {
         ANGLE_TRY(ensureRenderTarget(context));
-        ASSERT(isValidFaceLevel(faceIndex, destLevel));
-        ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, destLevel));
+        ASSERT(isValidFaceLevel(faceIndex, index.mipIndex));
+        ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, index.mipIndex));
 
         const gl::InternalFormat &internalFormatInfo =
-            gl::GetSizedInternalFormatInfo(getInternalFormat(destLevel, faceIndex));
+            gl::GetSizedInternalFormatInfo(getInternalFormat(index.mipIndex, faceIndex));
         ANGLE_TRY(mRenderer->copyTexture(
             context, source, static_cast<GLint>(sourceLevel), sourceArea, internalFormatInfo.format,
-            internalFormatInfo.type, destOffset, mTexStorage, target, destLevel, unpackFlipY,
-            unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+            internalFormatInfo.type, destOffset, mTexStorage, index.target, index.mipIndex,
+            unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
     }
     else
     {
         gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(static_cast<GLint>(sourceLevel));
         TextureD3D *sourceD3D           = GetImplAs<TextureD3D>(source);
         ImageD3D *sourceImage           = nullptr;
         ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage));
 
-        gl::ImageIndex destImageIndex =
-            gl::ImageIndex::MakeCube(target, static_cast<GLint>(destLevel));
         ImageD3D *destImage = nullptr;
-        ANGLE_TRY(getImageAndSyncFromStorage(context, destImageIndex, &destImage));
+        ANGLE_TRY(getImageAndSyncFromStorage(context, index, &destImage));
 
         ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceArea, destOffset,
                                        unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
 
         mDirtyImages = true;
 
         gl::Box destRegion(destOffset.x, destOffset.y, 0, sourceArea.width, sourceArea.height, 1);
-        ANGLE_TRY(commitRegion(context, destImageIndex, destRegion));
+        ANGLE_TRY(commitRegion(context, index, destRegion));
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_Cube::setStorage(const gl::Context *context,
-                                      GLenum target,
+                                      gl::TextureType type,
                                       size_t levels,
                                       GLenum internalFormat,
                                       const gl::Extents &size)
 {
     ASSERT(size.width == size.height);
     ASSERT(size.depth == 1);
 
     for (size_t level = 0; level < levels; level++)
     {
         GLsizei mipSize = std::max(1, size.width >> level);
         for (int faceIndex = 0; faceIndex < 6; faceIndex++)
         {
-            mImageArray[faceIndex][level]->redefine(GL_TEXTURE_CUBE_MAP, internalFormat, gl::Extents(mipSize, mipSize, 1), true);
+            mImageArray[faceIndex][level]->redefine(gl::TextureType::CubeMap, internalFormat,
+                                                    gl::Extents(mipSize, mipSize, 1), true);
         }
     }
 
     for (size_t level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
     {
         for (int faceIndex = 0; faceIndex < 6; faceIndex++)
         {
-            mImageArray[faceIndex][level]->redefine(GL_TEXTURE_CUBE_MAP, GL_NONE, gl::Extents(0, 0, 0), true);
+            mImageArray[faceIndex][level]->redefine(gl::TextureType::CubeMap, GL_NONE,
+                                                    gl::Extents(0, 0, 0), true);
         }
     }
 
     // TODO(geofflang): Verify storage creation had no errors
     bool renderTarget = IsRenderTargetUsage(mState.getUsage());
 
     TexStoragePointer storage(context);
     storage.reset(mRenderer->createTextureStorageCube(internalFormat, renderTarget, size.width,
@@ -2058,17 +1996,17 @@ gl::Error TextureD3D_Cube::initMipmapIma
     }
     return gl::NoError();
 }
 
 gl::Error TextureD3D_Cube::getRenderTarget(const gl::Context *context,
                                            const gl::ImageIndex &index,
                                            RenderTargetD3D **outRT)
 {
-    ASSERT(gl::IsCubeMapTextureTarget(index.target));
+    ASSERT(gl::TextureTargetToType(index.target) == gl::TextureType::CubeMap);
 
     // ensure the underlying texture is created
     ANGLE_TRY(ensureRenderTarget(context));
     ANGLE_TRY(updateStorageFaceLevel(context, index.cubeMapFaceIndex(), index.mipIndex));
 
     return mTexStorage->getRenderTarget(context, index, outRT);
 }
 
@@ -2240,17 +2178,17 @@ gl::Error TextureD3D_Cube::updateStorage
                                                   int level)
 {
     ASSERT(level >= 0 && faceIndex < 6 && level < static_cast<int>(mImageArray[faceIndex].size()) &&
            mImageArray[faceIndex][level] != nullptr);
     ImageD3D *image = mImageArray[faceIndex][level].get();
 
     if (image->isDirty())
     {
-        GLenum faceTarget = gl::LayerIndexToCubeMapTextureTarget(faceIndex);
+        gl::TextureTarget faceTarget = gl::CubeFaceIndexToTextureTarget(faceIndex);
         gl::ImageIndex index = gl::ImageIndex::MakeCube(faceTarget, level);
         gl::Box region(0, 0, 0, image->getWidth(), image->getHeight(), 1);
         ANGLE_TRY(commitRegion(context, index, region));
     }
 
     return gl::NoError();
 }
 
@@ -2261,17 +2199,17 @@ gl::Error TextureD3D_Cube::redefineImage
                                          const gl::Extents &size,
                                          bool forceRelease)
 {
     // If there currently is a corresponding storage texture image, it has these parameters
     const int storageWidth     = std::max(1, getLevelZeroWidth() >> level);
     const int storageHeight    = std::max(1, getLevelZeroHeight() >> level);
     const GLenum storageFormat = getBaseLevelInternalFormat();
 
-    mImageArray[faceIndex][level]->redefine(GL_TEXTURE_CUBE_MAP, internalformat, size,
+    mImageArray[faceIndex][level]->redefine(gl::TextureType::CubeMap, internalformat, size,
                                             forceRelease);
     mDirtyImages = mDirtyImages || mImageArray[faceIndex][level]->isDirty();
 
     if (mTexStorage)
     {
         const int storageLevels = mTexStorage->getLevelCount();
 
         if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth ||
@@ -2289,24 +2227,24 @@ gl::Error TextureD3D_Cube::redefineImage
 gl::ImageIndexIterator TextureD3D_Cube::imageIterator() const
 {
     return gl::ImageIndexIterator::MakeCube(0, mTexStorage->getLevelCount());
 }
 
 gl::ImageIndex TextureD3D_Cube::getImageIndex(GLint mip, GLint layer) const
 {
     // The "layer" of the image index corresponds to the cube face
-    return gl::ImageIndex::MakeCube(gl::LayerIndexToCubeMapTextureTarget(layer), mip);
+    return gl::ImageIndex::MakeCube(gl::CubeFaceIndexToTextureTarget(layer), mip);
 }
 
 bool TextureD3D_Cube::isValidIndex(const gl::ImageIndex &index) const
 {
-    return (mTexStorage && index.type == GL_TEXTURE_CUBE_MAP &&
-            gl::IsCubeMapTextureTarget(index.target) && index.mipIndex >= 0 &&
-            index.mipIndex < mTexStorage->getLevelCount());
+    return (mTexStorage && index.type == gl::TextureType::CubeMap &&
+            gl::TextureTargetToType(index.target) == gl::TextureType::CubeMap &&
+            index.mipIndex >= 0 && index.mipIndex < mTexStorage->getLevelCount());
 }
 
 void TextureD3D_Cube::markAllImagesDirty()
 {
     for (int dirtyLevel = 0; dirtyLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; dirtyLevel++)
     {
         for (int dirtyFace = 0; dirtyFace < 6; dirtyFace++)
         {
@@ -2347,17 +2285,17 @@ ImageD3D *TextureD3D_3D::getImage(int le
     ASSERT(layer == 0);
     return mImageArray[level].get();
 }
 
 ImageD3D *TextureD3D_3D::getImage(const gl::ImageIndex &index) const
 {
     ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
     ASSERT(!index.hasLayer());
-    ASSERT(index.type == GL_TEXTURE_3D);
+    ASSERT(index.type == gl::TextureType::_3D);
     return mImageArray[index.mipIndex].get();
 }
 
 GLsizei TextureD3D_3D::getLayerCount(int level) const
 {
     ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
     return 1;
 }
@@ -2395,160 +2333,145 @@ GLenum TextureD3D_3D::getInternalFormat(
 }
 
 bool TextureD3D_3D::isDepth(GLint level) const
 {
     return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
 }
 
 gl::Error TextureD3D_3D::setEGLImageTarget(const gl::Context *context,
-                                           GLenum target,
+                                           gl::TextureType type,
                                            egl::Image *image)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_3D::setImage(const gl::Context *context,
-                                  GLenum target,
-                                  size_t imageLevel,
+                                  const gl::ImageIndex &index,
                                   GLenum internalFormat,
                                   const gl::Extents &size,
                                   GLenum format,
                                   GLenum type,
                                   const gl::PixelUnpackState &unpack,
                                   const uint8_t *pixels)
 {
-    ASSERT(target == GL_TEXTURE_3D);
+    ASSERT(index.target == gl::TextureTarget::_3D);
     const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
 
-    GLint level = static_cast<GLint>(imageLevel);
-    ANGLE_TRY(redefineImage(context, level, internalFormatInfo.sizedInternalFormat, size, false));
+    ANGLE_TRY(redefineImage(context, index.mipIndex, internalFormatInfo.sizedInternalFormat, size,
+                            false));
 
     bool fastUnpacked = false;
 
-    gl::ImageIndex index = gl::ImageIndex::Make3D(level);
-
     // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
     gl::Buffer *unpackBuffer =
         context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
     if (isFastUnpackable(unpackBuffer, internalFormatInfo.sizedInternalFormat) && !size.empty() &&
-        isLevelComplete(level))
+        isLevelComplete(index.mipIndex))
     {
         // Will try to create RT storage if it does not exist
         RenderTargetD3D *destRenderTarget = nullptr;
         ANGLE_TRY(getRenderTarget(context, index, &destRenderTarget));
 
-        gl::Box destArea(0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
+        gl::Box destArea(0, 0, 0, getWidth(index.mipIndex), getHeight(index.mipIndex),
+                         getDepth(index.mipIndex));
 
         ANGLE_TRY(fastUnpackPixels(context, unpack, pixels, destArea,
                                    internalFormatInfo.sizedInternalFormat, type, destRenderTarget));
 
         // Ensure we don't overwrite our newly initialized data
-        mImageArray[level]->markClean();
+        mImageArray[index.mipIndex]->markClean();
 
         fastUnpacked = true;
     }
 
     if (!fastUnpacked)
     {
         ANGLE_TRY(setImageImpl(context, index, type, unpack, pixels, 0));
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_3D::setSubImage(const gl::Context *context,
-                                     GLenum target,
-                                     size_t imageLevel,
+                                     const gl::ImageIndex &index,
                                      const gl::Box &area,
                                      GLenum format,
                                      GLenum type,
                                      const gl::PixelUnpackState &unpack,
                                      const uint8_t *pixels)
 {
-    ASSERT(target == GL_TEXTURE_3D);
-
-    GLint level          = static_cast<GLint>(imageLevel);
-    gl::ImageIndex index = gl::ImageIndex::Make3D(level);
+    ASSERT(index.target == gl::TextureTarget::_3D);
 
     // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
     gl::Buffer *unpackBuffer =
         context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
-    if (isFastUnpackable(unpackBuffer, getInternalFormat(level)) && isLevelComplete(level))
+    GLenum mipFormat = getInternalFormat(index.mipIndex);
+    if (isFastUnpackable(unpackBuffer, mipFormat) && isLevelComplete(index.mipIndex))
     {
         RenderTargetD3D *destRenderTarget = nullptr;
         ANGLE_TRY(getRenderTarget(context, index, &destRenderTarget));
-        ASSERT(!mImageArray[level]->isDirty());
-
-        return fastUnpackPixels(context, unpack, pixels, area, getInternalFormat(level), type,
-                                destRenderTarget);
+        ASSERT(!mImageArray[index.mipIndex]->isDirty());
+
+        return fastUnpackPixels(context, unpack, pixels, area, mipFormat, type, destRenderTarget);
     }
     else
     {
         return TextureD3D::subImage(context, index, area, format, type, unpack, pixels, 0);
     }
 }
 
 gl::Error TextureD3D_3D::setCompressedImage(const gl::Context *context,
-                                            GLenum target,
-                                            size_t imageLevel,
+                                            const gl::ImageIndex &index,
                                             GLenum internalFormat,
                                             const gl::Extents &size,
                                             const gl::PixelUnpackState &unpack,
                                             size_t imageSize,
                                             const uint8_t *pixels)
 {
-    ASSERT(target == GL_TEXTURE_3D);
-
-    GLint level = static_cast<GLint>(imageLevel);
+    ASSERT(index.target == gl::TextureTarget::_3D);
+
     // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
-    ANGLE_TRY(redefineImage(context, level, internalFormat, size, false));
-
-    gl::ImageIndex index = gl::ImageIndex::Make3D(level);
+    ANGLE_TRY(redefineImage(context, index.mipIndex, internalFormat, size, false));
+
     return setCompressedImageImpl(context, index, unpack, pixels, 0);
 }
 
 gl::Error TextureD3D_3D::setCompressedSubImage(const gl::Context *context,
-                                               GLenum target,
-                                               size_t level,
+                                               const gl::ImageIndex &index,
                                                const gl::Box &area,
                                                GLenum format,
                                                const gl::PixelUnpackState &unpack,
                                                size_t imageSize,
                                                const uint8_t *pixels)
 {
-    ASSERT(target == GL_TEXTURE_3D);
-
-    gl::ImageIndex index = gl::ImageIndex::Make3D(static_cast<GLint>(level));
+    ASSERT(index.target == gl::TextureTarget::_3D);
+
     ANGLE_TRY(TextureD3D::subImageCompressed(context, index, area, format, unpack, pixels, 0));
     return commitRegion(context, index, area);
 }
 
 gl::Error TextureD3D_3D::copyImage(const gl::Context *context,
-                                   GLenum target,
-                                   size_t level,
+                                   const gl::ImageIndex &index,
                                    const gl::Rectangle &sourceArea,
                                    GLenum internalFormat,
-                                   const gl::Framebuffer *source)
+                                   gl::Framebuffer *source)
 {
     UNIMPLEMENTED();
     return gl::InternalError() << "Copying 3D textures is unimplemented.";
 }
 
 gl::Error TextureD3D_3D::copySubImage(const gl::Context *context,
-                                      GLenum target,
-                                      size_t imageLevel,
+                                      const gl::ImageIndex &index,
                                       const gl::Offset &destOffset,
                                       const gl::Rectangle &sourceArea,
-                                      const gl::Framebuffer *source)
+                                      gl::Framebuffer *source)
 {
-    ASSERT(target == GL_TEXTURE_3D);
-
-    GLint level = static_cast<GLint>(imageLevel);
+    ASSERT(index.target == gl::TextureTarget::_3D);
 
     gl::Extents fbSize = source->getReadColorbuffer()->getSize();
     gl::Rectangle clippedSourceArea;
     if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height),
                        &clippedSourceArea))
     {
         return gl::NoError();
     }
@@ -2556,53 +2479,52 @@ gl::Error TextureD3D_3D::copySubImage(co
                                        destOffset.y + clippedSourceArea.y - sourceArea.y,
                                        destOffset.z);
 
     // Currently, copying directly to the storage is not possible because it's not possible to
     // create an SRV from a single layer of a 3D texture.  Instead, make sure the image is up to
     // date before the copy and then copy back to the storage afterwards if needed.
     // TODO: Investigate 3D blits in D3D11.
 
-    bool syncTexStorage = mTexStorage && isLevelComplete(level);
+    bool syncTexStorage = mTexStorage && isLevelComplete(index.mipIndex);
     if (syncTexStorage)
     {
-        gl::ImageIndex index = gl::ImageIndex::Make3D(level);
-        ANGLE_TRY(mImageArray[level]->copyFromTexStorage(context, index, mTexStorage));
+        ANGLE_TRY(mImageArray[index.mipIndex]->copyFromTexStorage(context, index, mTexStorage));
     }
-    ANGLE_TRY(mImageArray[level]->copyFromFramebuffer(context, clippedDestOffset, clippedSourceArea,
-                                                      source));
+    ANGLE_TRY(mImageArray[index.mipIndex]->copyFromFramebuffer(context, clippedDestOffset,
+                                                               clippedSourceArea, source));
     mDirtyImages = true;
 
     if (syncTexStorage)
     {
-        ANGLE_TRY(updateStorageLevel(context, level));
+        ANGLE_TRY(updateStorageLevel(context, index.mipIndex));
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_3D::setStorage(const gl::Context *context,
-                                    GLenum target,
+                                    gl::TextureType type,
                                     size_t levels,
                                     GLenum internalFormat,
                                     const gl::Extents &size)
 {
-    ASSERT(target == GL_TEXTURE_3D);
+    ASSERT(type == gl::TextureType::_3D);
 
     for (size_t level = 0; level < levels; level++)
     {
         gl::Extents levelSize(std::max(1, size.width >> level),
                               std::max(1, size.height >> level),
                               std::max(1, size.depth >> level));
-        mImageArray[level]->redefine(GL_TEXTURE_3D, internalFormat, levelSize, true);
+        mImageArray[level]->redefine(gl::TextureType::_3D, internalFormat, levelSize, true);
     }
 
     for (size_t level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
     {
-        mImageArray[level]->redefine(GL_TEXTURE_3D, GL_NONE, gl::Extents(0, 0, 0), true);
+        mImageArray[level]->redefine(gl::TextureType::_3D, GL_NONE, gl::Extents(0, 0, 0), true);
     }
 
     // TODO(geofflang): Verify storage creation had no errors
     bool renderTarget = IsRenderTargetUsage(mState.getUsage());
     TexStoragePointer storage(context);
     storage.reset(mRenderer->createTextureStorage3D(internalFormat, renderTarget, size.width,
                                                     size.height, size.depth,
                                                     static_cast<int>(levels)));
@@ -2831,17 +2753,17 @@ gl::Error TextureD3D_3D::redefineImage(c
                                        bool forceRelease)
 {
     // If there currently is a corresponding storage texture image, it has these parameters
     const int storageWidth  = std::max(1, getLevelZeroWidth() >> level);
     const int storageHeight = std::max(1, getLevelZeroHeight() >> level);
     const int storageDepth  = std::max(1, getLevelZeroDepth() >> level);
     const GLenum storageFormat = getBaseLevelInternalFormat();
 
-    mImageArray[level]->redefine(GL_TEXTURE_3D, internalformat, size, forceRelease);
+    mImageArray[level]->redefine(gl::TextureType::_3D, internalformat, size, forceRelease);
     mDirtyImages = mDirtyImages || mImageArray[level]->isDirty();
 
     if (mTexStorage)
     {
         const int storageLevels = mTexStorage->getLevelCount();
 
         if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth ||
             size.height != storageHeight || size.depth != storageDepth ||
@@ -2864,17 +2786,17 @@ gl::ImageIndexIterator TextureD3D_3D::im
 gl::ImageIndex TextureD3D_3D::getImageIndex(GLint mip, GLint /*layer*/) const
 {
     // The "layer" here does not apply to 3D images. We use one Image per mip.
     return gl::ImageIndex::Make3D(mip);
 }
 
 bool TextureD3D_3D::isValidIndex(const gl::ImageIndex &index) const
 {
-    return (mTexStorage && index.type == GL_TEXTURE_3D && index.mipIndex >= 0 &&
+    return (mTexStorage && index.type == gl::TextureType::_3D && index.mipIndex >= 0 &&
             index.mipIndex < mTexStorage->getLevelCount());
 }
 
 void TextureD3D_3D::markAllImagesDirty()
 {
     for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
     {
         mImageArray[i]->markDirty();
@@ -2920,17 +2842,17 @@ ImageD3D *TextureD3D_2DArray::getImage(i
 }
 
 ImageD3D *TextureD3D_2DArray::getImage(const gl::ImageIndex &index) const
 {
     ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
     ASSERT(index.layerIndex != gl::ImageIndex::ENTIRE_LEVEL);
     ASSERT((index.layerIndex == 0 && mLayerCounts[index.mipIndex] == 0) ||
            index.layerIndex < mLayerCounts[index.mipIndex]);
-    ASSERT(index.type == GL_TEXTURE_2D_ARRAY);
+    ASSERT(index.type == gl::TextureType::_2DArray);
     return (mImageArray[index.mipIndex] ? mImageArray[index.mipIndex][index.layerIndex] : nullptr);
 }
 
 GLsizei TextureD3D_2DArray::getLayerCount(int level) const
 {
     ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
     return mLayerCounts[level];
 }
@@ -2951,219 +2873,205 @@ GLenum TextureD3D_2DArray::getInternalFo
 }
 
 bool TextureD3D_2DArray::isDepth(GLint level) const
 {
     return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
 }
 
 gl::Error TextureD3D_2DArray::setEGLImageTarget(const gl::Context *context,
-                                                GLenum target,
+                                                gl::TextureType type,
                                                 egl::Image *image)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_2DArray::setImage(const gl::Context *context,
-                                       GLenum target,
-                                       size_t imageLevel,
+                                       const gl::ImageIndex &index,
                                        GLenum internalFormat,
                                        const gl::Extents &size,
                                        GLenum format,
                                        GLenum type,
                                        const gl::PixelUnpackState &unpack,
                                        const uint8_t *pixels)
 {
-    ASSERT(target == GL_TEXTURE_2D_ARRAY);
+    ASSERT(index.target == gl::TextureTarget::_2DArray);
 
     const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type);
-    const gl::InternalFormat &packFormat = gl::GetPackFormatInfo(format, type);
-
-    GLint level = static_cast<GLint>(imageLevel);
-    ANGLE_TRY(redefineImage(context, level, formatInfo.sizedInternalFormat, size, false));
+
+    ANGLE_TRY(redefineImage(context, index.mipIndex, formatInfo.sizedInternalFormat, size, false));
 
     GLsizei inputDepthPitch              = 0;
-    ANGLE_TRY_RESULT(packFormat.computeDepthPitch(size.width, size.height, unpack.alignment,
+    ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(type, size.width, size.height, unpack.alignment,
                                                   unpack.rowLength, unpack.imageHeight),
                      inputDepthPitch);
 
     for (int i = 0; i < size.depth; i++)
     {
         const ptrdiff_t layerOffset = (inputDepthPitch * i);
-        gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, i);
-        ANGLE_TRY(setImageImpl(context, index, type, unpack, pixels, layerOffset));
+        gl::ImageIndex layerIndex   = gl::ImageIndex::Make2DArray(index.mipIndex, i);
+        ANGLE_TRY(setImageImpl(context, layerIndex, type, unpack, pixels, layerOffset));
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2DArray::setSubImage(const gl::Context *context,
-                                          GLenum target,
-                                          size_t imageLevel,
+                                          const gl::ImageIndex &index,
                                           const gl::Box &area,
                                           GLenum format,
                                           GLenum type,
                                           const gl::PixelUnpackState &unpack,
                                           const uint8_t *pixels)
 {
-    ASSERT(target == GL_TEXTURE_2D_ARRAY);
-    GLint level                          = static_cast<GLint>(imageLevel);
-    const gl::InternalFormat &packFormat =
-        gl::GetPackFormatInfo(getInternalFormat(level), type);
-
+    ASSERT(index.target == gl::TextureTarget::_2DArray);
+    const gl::InternalFormat &formatInfo =
+        gl::GetInternalFormatInfo(getInternalFormat(index.mipIndex), type);
     GLsizei inputDepthPitch              = 0;
-    ANGLE_TRY_RESULT(packFormat.computeDepthPitch(area.width, area.height, unpack.alignment,
+    ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(type, area.width, area.height, unpack.alignment,
                                                   unpack.rowLength, unpack.imageHeight),
                      inputDepthPitch);
 
     for (int i = 0; i < area.depth; i++)
     {
         int layer = area.z + i;
         const ptrdiff_t layerOffset = (inputDepthPitch * i);
 
         gl::Box layerArea(area.x, area.y, 0, area.width, area.height, 1);
 
-        gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer);
-        ANGLE_TRY(TextureD3D::subImage(context, index, layerArea, format, type, unpack, pixels,
+        gl::ImageIndex layerIndex = gl::ImageIndex::Make2DArray(index.mipIndex, layer);
+        ANGLE_TRY(TextureD3D::subImage(context, layerIndex, layerArea, format, type, unpack, pixels,
                                        layerOffset));
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2DArray::setCompressedImage(const gl::Context *context,
-                                                 GLenum target,
-                                                 size_t imageLevel,
+                                                 const gl::ImageIndex &index,
                                                  GLenum internalFormat,
                                                  const gl::Extents &size,
                                                  const gl::PixelUnpackState &unpack,
                                                  size_t imageSize,
                                                  const uint8_t *pixels)
 {
-    ASSERT(target == GL_TEXTURE_2D_ARRAY);
-
-    GLint level = static_cast<GLint>(imageLevel);
+    ASSERT(index.target == gl::TextureTarget::_2DArray);
+
     // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
-    ANGLE_TRY(redefineImage(context, level, internalFormat, size, false));
+    ANGLE_TRY(redefineImage(context, index.mipIndex, internalFormat, size, false));
 
     const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
     GLsizei inputDepthPitch              = 0;
     ANGLE_TRY_RESULT(
-        formatInfo.computeDepthPitch(size.width, size.height, 1, 0, 0),
+        formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, size.width, size.height, 1, 0, 0),
         inputDepthPitch);
 
     for (int i = 0; i < size.depth; i++)
     {
         const ptrdiff_t layerOffset = (inputDepthPitch * i);
 
-        gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, i);
-        ANGLE_TRY(setCompressedImageImpl(context, index, unpack, pixels, layerOffset));
+        gl::ImageIndex layerIndex = gl::ImageIndex::Make2DArray(index.mipIndex, i);
+        ANGLE_TRY(setCompressedImageImpl(context, layerIndex, unpack, pixels, layerOffset));
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2DArray::setCompressedSubImage(const gl::Context *context,
-                                                    GLenum target,
-                                                    size_t level,
+                                                    const gl::ImageIndex &index,
                                                     const gl::Box &area,
                                                     GLenum format,
                                                     const gl::PixelUnpackState &unpack,
                                                     size_t imageSize,
                                                     const uint8_t *pixels)
 {
-    ASSERT(target == GL_TEXTURE_2D_ARRAY);
+    ASSERT(index.target == gl::TextureTarget::_2DArray);
 
     const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(format);
     GLsizei inputDepthPitch              = 0;
     ANGLE_TRY_RESULT(
-        formatInfo.computeDepthPitch(area.width, area.height, 1, 0, 0),
+        formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0),
         inputDepthPitch);
 
     for (int i = 0; i < area.depth; i++)
     {
         int layer = area.z + i;
         const ptrdiff_t layerOffset = (inputDepthPitch * i);
 
         gl::Box layerArea(area.x, area.y, 0, area.width, area.height, 1);
 
-        gl::ImageIndex index = gl::ImageIndex::Make2DArray(static_cast<GLint>(level), layer);
-        ANGLE_TRY(TextureD3D::subImageCompressed(context, index, layerArea, format, unpack, pixels,
-                                                 layerOffset));
-        ANGLE_TRY(commitRegion(context, index, layerArea));
+        gl::ImageIndex layerIndex = gl::ImageIndex::Make2DArray(index.mipIndex, layer);
+        ANGLE_TRY(TextureD3D::subImageCompressed(context, layerIndex, layerArea, format, unpack,
+                                                 pixels, layerOffset));
+        ANGLE_TRY(commitRegion(context, layerIndex, layerArea));
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2DArray::copyImage(const gl::Context *context,
-                                        GLenum target,
-                                        size_t level,
+                                        const gl::ImageIndex &index,
                                         const gl::Rectangle &sourceArea,
                                         GLenum internalFormat,
-                                        const gl::Framebuffer *source)
+                                        gl::Framebuffer *source)
 {
     UNIMPLEMENTED();
     return gl::InternalError() << "Copying 2D array textures is unimplemented.";
 }
 
 gl::Error TextureD3D_2DArray::copySubImage(const gl::Context *context,
-                                           GLenum target,
-                                           size_t imageLevel,
+                                           const gl::ImageIndex &index,
                                            const gl::Offset &destOffset,
                                            const gl::Rectangle &sourceArea,
-                                           const gl::Framebuffer *source)
+                                           gl::Framebuffer *source)
 {
-    ASSERT(target == GL_TEXTURE_2D_ARRAY);
-
-    GLint level          = static_cast<GLint>(imageLevel);
-    gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, destOffset.z);
+    ASSERT(index.target == gl::TextureTarget::_2DArray);
 
     gl::Extents fbSize = source->getReadColorbuffer()->getSize();
     gl::Rectangle clippedSourceArea;
     if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height),
                        &clippedSourceArea))
     {
         return gl::NoError();
     }
     const gl::Offset clippedDestOffset(destOffset.x + clippedSourceArea.x - sourceArea.x,
                                        destOffset.y + clippedSourceArea.y - sourceArea.y,
                                        destOffset.z);
 
     if (!canCreateRenderTargetForImage(index))
     {
         gl::Offset destLayerOffset(clippedDestOffset.x, clippedDestOffset.y, 0);
-        ANGLE_TRY(mImageArray[level][clippedDestOffset.z]->copyFromFramebuffer(
+        ANGLE_TRY(mImageArray[index.mipIndex][clippedDestOffset.z]->copyFromFramebuffer(
             context, destLayerOffset, clippedSourceArea, source));
         mDirtyImages = true;
     }
     else
     {
         ANGLE_TRY(ensureRenderTarget(context));
 
-        if (isValidLevel(level))
+        if (isValidLevel(index.mipIndex))
         {
-            ANGLE_TRY(updateStorageLevel(context, level));
+            ANGLE_TRY(updateStorageLevel(context, index.mipIndex));
             ANGLE_TRY(
                 mRenderer->copyImage2DArray(context, source, clippedSourceArea,
                                             gl::GetUnsizedFormat(getInternalFormat(getBaseLevel())),
-                                            clippedDestOffset, mTexStorage, level));
+                                            clippedDestOffset, mTexStorage, index.mipIndex));
         }
     }
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2DArray::setStorage(const gl::Context *context,
-                                         GLenum target,
+                                         gl::TextureType type,
                                          size_t levels,
                                          GLenum internalFormat,
                                          const gl::Extents &size)
 {
-    ASSERT(target == GL_TEXTURE_2D_ARRAY);
+    ASSERT(type == gl::TextureType::_2DArray);
 
     deleteImages();
 
     for (size_t level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
     {
         gl::Extents levelLayerSize(std::max(1, size.width >> level),
                                    std::max(1, size.height >> level),
                                    1);
@@ -3173,17 +3081,18 @@ gl::Error TextureD3D_2DArray::setStorage
         if (mLayerCounts[level] > 0)
         {
             // Create new images for this level
             mImageArray[level] = new ImageD3D*[mLayerCounts[level]];
 
             for (int layer = 0; layer < mLayerCounts[level]; layer++)
             {
                 mImageArray[level][layer] = mRenderer->createImage();
-                mImageArray[level][layer]->redefine(GL_TEXTURE_2D_ARRAY, internalFormat, levelLayerSize, true);
+                mImageArray[level][layer]->redefine(gl::TextureType::_2DArray, internalFormat,
+                                                    levelLayerSize, true);
             }
         }
     }
 
     // TODO(geofflang): Verify storage creation had no errors
     bool renderTarget = IsRenderTargetUsage(mState.getUsage());
     TexStoragePointer storage(context);
     storage.reset(mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, size.width,
@@ -3463,17 +3372,17 @@ gl::Error TextureD3D_2DArray::redefineIm
             }
         }
     }
 
     if (size.depth > 0)
     {
         for (int layer = 0; layer < mLayerCounts[level]; layer++)
         {
-            mImageArray[level][layer]->redefine(GL_TEXTURE_2D_ARRAY, internalformat,
+            mImageArray[level][layer]->redefine(gl::TextureType::_2DArray, internalformat,
                                                 gl::Extents(size.width, size.height, 1),
                                                 forceRelease);
             mDirtyImages = mDirtyImages || mImageArray[level][layer]->isDirty();
         }
     }
 
     if (mTexStorage)
     {
@@ -3499,17 +3408,17 @@ gl::ImageIndexIterator TextureD3D_2DArra
 gl::ImageIndex TextureD3D_2DArray::getImageIndex(GLint mip, GLint layer) const
 {
     return gl::ImageIndex::Make2DArray(mip, layer);
 }
 
 bool TextureD3D_2DArray::isValidIndex(const gl::ImageIndex &index) const
 {
     // Check for having a storage and the right type of index
-    if (!mTexStorage || index.type != GL_TEXTURE_2D_ARRAY)
+    if (!mTexStorage || index.type != gl::TextureType::_2DArray)
     {
         return false;
     }
 
     // Check the mip index
     if (index.mipIndex < 0 || index.mipIndex >= mTexStorage->getLevelCount())
     {
         return false;
@@ -3547,107 +3456,101 @@ ImageD3D *TextureD3D_External::getImage(
 }
 
 GLsizei TextureD3D_External::getLayerCount(int level) const
 {
     return 1;
 }
 
 gl::Error TextureD3D_External::setImage(const gl::Context *context,
-                                        GLenum target,
-                                        size_t imageLevel,
+                                        const gl::ImageIndex &index,
                                         GLenum internalFormat,
                                         const gl::Extents &size,
                                         GLenum format,
                                         GLenum type,
                                         const gl::PixelUnpackState &unpack,
                                         const uint8_t *pixels)
 {
     // Image setting is not supported for external images
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_External::setSubImage(const gl::Context *context,
-                                           GLenum target,
-                                           size_t imageLevel,
+                                           const gl::ImageIndex &index,
                                            const gl::Box &area,
                                            GLenum format,
                                            GLenum type,
                                            const gl::PixelUnpackState &unpack,
                                            const uint8_t *pixels)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_External::setCompressedImage(const gl::Context *context,
-                                                  GLenum target,
-                                                  size_t imageLevel,
+                                                  const gl::ImageIndex &index,
                                                   GLenum internalFormat,
                                                   const gl::Extents &size,
                                                   const gl::PixelUnpackState &unpack,
                                                   size_t imageSize,
                                                   const uint8_t *pixels)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_External::setCompressedSubImage(const gl::Context *context,
-                                                     GLenum target,
-                                                     size_t level,
+                                                     const gl::ImageIndex &index,
                                                      const gl::Box &area,
                                                      GLenum format,
                                                      const gl::PixelUnpackState &unpack,
                                                      size_t imageSize,
                                                      const uint8_t *pixels)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_External::copyImage(const gl::Context *context,
-                                         GLenum target,
-                                         size_t imageLevel,
+                                         const gl::ImageIndex &index,
                                          const gl::Rectangle &sourceArea,
                                          GLenum internalFormat,
-                                         const gl::Framebuffer *source)
+                                         gl::Framebuffer *source)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_External::copySubImage(const gl::Context *context,
-                                            GLenum target,
-                                            size_t imageLevel,
+                                            const gl::ImageIndex &index,
                                             const gl::Offset &destOffset,
                                             const gl::Rectangle &sourceArea,
-                                            const gl::Framebuffer *source)
+                                            gl::Framebuffer *source)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_External::setStorage(const gl::Context *context,
-                                          GLenum target,
+                                          gl::TextureType type,
                                           size_t levels,
                                           GLenum internalFormat,
                                           const gl::Extents &size)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_External::setImageExternal(const gl::Context *context,
-                                                GLenum target,
+                                                gl::TextureType type,
                                                 egl::Stream *stream,
                                                 const egl::Stream::GLTextureDescription &desc)
 {
-    ASSERT(target == GL_TEXTURE_EXTERNAL_OES);
+    ASSERT(type == gl::TextureType::External);
 
     ANGLE_TRY(releaseTexStorage(context));
 
     // If the stream is null, the external image is unbound and we release the storage
     if (stream != nullptr)
     {
         mTexStorage = mRenderer->createTextureStorageExternal(stream, desc);
     }
@@ -3663,17 +3566,17 @@ gl::Error TextureD3D_External::bindTexIm
 
 gl::Error TextureD3D_External::releaseTexImage(const gl::Context *context)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_External::setEGLImageTarget(const gl::Context *context,
-                                                 GLenum target,
+                                                 gl::TextureType type,
                                                  egl::Image *image)
 {
     EGLImageD3D *eglImaged3d = GetImplAs<EGLImageD3D>(image);
 
     // Pass in the RenderTargetD3D here: createTextureStorage can't generate an error.
     RenderTargetD3D *renderTargetD3D = nullptr;
     ANGLE_TRY(eglImaged3d->getRenderTarget(context, &renderTargetD3D));
 
@@ -3739,17 +3642,17 @@ gl::ImageIndexIterator TextureD3D_Extern
 gl::ImageIndex TextureD3D_External::getImageIndex(GLint mip, GLint /*layer*/) const
 {
     // "layer" does not apply to 2D Textures.
     return gl::ImageIndex::Make2D(mip);
 }
 
 bool TextureD3D_External::isValidIndex(const gl::ImageIndex &index) const
 {
-    return (mTexStorage && index.type == GL_TEXTURE_EXTERNAL_OES && index.mipIndex == 0);
+    return (mTexStorage && index.type == gl::TextureType::External && index.mipIndex == 0);
 }
 
 void TextureD3D_External::markAllImagesDirty()
 {
     UNREACHABLE();
 }
 
 TextureD3D_2DMultisample::TextureD3D_2DMultisample(const gl::TextureState &state,
@@ -3763,98 +3666,92 @@ TextureD3D_2DMultisample::~TextureD3D_2D
 }
 
 ImageD3D *TextureD3D_2DMultisample::getImage(const gl::ImageIndex &index) const
 {
     return nullptr;
 }
 
 gl::Error TextureD3D_2DMultisample::setImage(const gl::Context *context,
-                                             GLenum target,
-                                             size_t level,
+                                             const gl::ImageIndex &index,
                                              GLenum internalFormat,
                                              const gl::Extents &size,
                                              GLenum format,
                                              GLenum type,
                                              const gl::PixelUnpackState &unpack,
                                              const uint8_t *pixels)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_2DMultisample::setSubImage(const gl::Context *context,
-                                                GLenum target,
-                                                size_t level,
+                                                const gl::ImageIndex &index,
                                                 const gl::Box &area,
                                                 GLenum format,
                                                 GLenum type,
                                                 const gl::PixelUnpackState &unpack,
                                                 const uint8_t *pixels)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_2DMultisample::setCompressedImage(const gl::Context *context,
-                                                       GLenum target,
-                                                       size_t level,
+                                                       const gl::ImageIndex &index,
                                                        GLenum internalFormat,
                                                        const gl::Extents &size,
                                                        const gl::PixelUnpackState &unpack,
                                                        size_t imageSize,
                                                        const uint8_t *pixels)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_2DMultisample::setCompressedSubImage(const gl::Context *context,
-                                                          GLenum target,
-                                                          size_t level,
+                                                          const gl::ImageIndex &index,
                                                           const gl::Box &area,
                                                           GLenum format,
                                                           const gl::PixelUnpackState &unpack,
                                                           size_t imageSize,
                                                           const uint8_t *pixels)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_2DMultisample::copyImage(const gl::Context *context,
-                                              GLenum target,
-                                              size_t level,
+                                              const gl::ImageIndex &index,
                                               const gl::Rectangle &sourceArea,
                                               GLenum internalFormat,
-                                              const gl::Framebuffer *source)
+                                              gl::Framebuffer *source)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_2DMultisample::copySubImage(const gl::Context *context,
-                                                 GLenum target,
-                                                 size_t level,
+                                                 const gl::ImageIndex &index,
                                                  const gl::Offset &destOffset,
                                                  const gl::Rectangle &sourceArea,
-                                                 const gl::Framebuffer *source)
+                                                 gl::Framebuffer *source)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_2DMultisample::setStorageMultisample(const gl::Context *context,
-                                                          GLenum target,
+                                                          gl::TextureType type,
                                                           GLsizei samples,
                                                           GLint internalFormat,
                                                           const gl::Extents &size,
                                                           bool fixedSampleLocations)
 {
-    ASSERT(target == GL_TEXTURE_2D_MULTISAMPLE && size.depth == 1);
+    ASSERT(type == gl::TextureType::_2DMultisample && size.depth == 1);
 
     TexStoragePointer storage(context);
     storage.reset(mRenderer->createTextureStorage2DMultisample(internalFormat, size.width,
                                                                size.height, static_cast<int>(0),
                                                                samples, fixedSampleLocations));
 
     ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
     storage.release();
@@ -3874,17 +3771,17 @@ gl::Error TextureD3D_2DMultisample::bind
 
 gl::Error TextureD3D_2DMultisample::releaseTexImage(const gl::Context *context)
 {
     UNREACHABLE();
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2DMultisample::setEGLImageTarget(const gl::Context *context,
-                                                      GLenum target,
+                                                      gl::TextureType type,
                                                       egl::Image *image)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_2DMultisample::getRenderTarget(const gl::Context *context,
                                                     const gl::ImageIndex &index,
@@ -3905,17 +3802,17 @@ gl::ImageIndexIterator TextureD3D_2DMult
 
 gl::ImageIndex TextureD3D_2DMultisample::getImageIndex(GLint mip, GLint layer) const
 {
     return gl::ImageIndex::Make2DMultisample();
 }
 
 bool TextureD3D_2DMultisample::isValidIndex(const gl::ImageIndex &index) const
 {
-    return (mTexStorage && index.type == GL_TEXTURE_2D_MULTISAMPLE && index.mipIndex == 0);
+    return (mTexStorage && index.type == gl::TextureType::_2DMultisample && index.mipIndex == 0);
 }
 
 GLsizei TextureD3D_2DMultisample::getLayerCount(int level) const
 {
     return 1;
 }
 
 void TextureD3D_2DMultisample::markAllImagesDirty()
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.h
@@ -52,23 +52,23 @@ class TextureD3D : public TextureImpl
                                          const gl::ImageIndex &index,
                                          ImageD3D **outImage);
 
     GLint getBaseLevelWidth() const;
     GLint getBaseLevelHeight() const;
     GLenum getBaseLevelInternalFormat() const;
 
     gl::Error setStorage(const gl::Context *context,
-                         GLenum target,
+                         gl::TextureType type,
                          size_t levels,
                          GLenum internalFormat,
                          const gl::Extents &size) override;
 
     gl::Error setStorageMultisample(const gl::Context *context,
-                                    GLenum target,
+                                    gl::TextureType type,
                                     GLsizei samples,
                                     GLint internalFormat,
                                     const gl::Extents &size,
                                     bool fixedSampleLocations) override;
 
     bool isImmutable() const { return mImmutable; }
 
     virtual gl::Error getRenderTarget(const gl::Context *context,
@@ -79,17 +79,17 @@ class TextureD3D : public TextureImpl
     virtual gl::ImageIndexIterator imageIterator() const = 0;
 
     // Returns an ImageIndex for a particular "Image". 3D Textures do not have images for
     // slices of their depth texures, so 3D textures ignore the layer parameter.
     virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const = 0;
     virtual bool isValidIndex(const gl::ImageIndex &index) const = 0;
 
     gl::Error setImageExternal(const gl::Context *context,
-                               GLenum target,
+                               gl::TextureType type,
                                egl::Stream *stream,
                                const egl::Stream::GLTextureDescription &desc) override;
     gl::Error generateMipmap(const gl::Context *context) override;
     TextureStorage *getStorage();
     ImageD3D *getBaseLevelImage() const;
 
     gl::Error getAttachmentRenderTarget(const gl::Context *context,
                                         GLenum binding,
@@ -200,96 +200,88 @@ class TextureD3D_2D : public TextureD3D
 
     GLsizei getWidth(GLint level) const;
     GLsizei getHeight(GLint level) const;
     GLenum getInternalFormat(GLint level) const;
     bool isDepth(GLint level) const;
     bool isSRGB(GLint level) const;
 
     gl::Error setImage(const gl::Context *context,
-                       GLenum target,
-                       size_t level,
+                       const gl::ImageIndex &index,
                        GLenum internalFormat,
                        const gl::Extents &size,
                        GLenum format,
                        GLenum type,
                        const gl::PixelUnpackState &unpack,
                        const uint8_t *pixels) override;
     gl::Error setSubImage(const gl::Context *context,
-                          GLenum target,
-                          size_t level,
+                          const gl::ImageIndex &index,
                           const gl::Box &area,
                           GLenum format,
                           GLenum type,
                           const gl::PixelUnpackState &unpack,
                           const uint8_t *pixels) override;
 
     gl::Error setCompressedImage(const gl::Context *context,
-                                 GLenum target,
-                                 size_t level,
+                                 const gl::ImageIndex &index,
                                  GLenum internalFormat,
                                  const gl::Extents &size,
                                  const gl::PixelUnpackState &unpack,
                                  size_t imageSize,
                                  const uint8_t *pixels) override;
     gl::Error setCompressedSubImage(const gl::Context *context,
-                                    GLenum target,
-                                    size_t level,
+                                    const gl::ImageIndex &index,
                                     const gl::Box &area,
                                     GLenum format,
                                     const gl::PixelUnpackState &unpack,
                                     size_t imageSize,
                                     const uint8_t *pixels) override;
 
     gl::Error copyImage(const gl::Context *context,
-                        GLenum target,
-                        size_t level,
+                        const gl::ImageIndex &index,
                         const gl::Rectangle &sourceArea,
                         GLenum internalFormat,
-                        const gl::Framebuffer *source) override;
+                        gl::Framebuffer *source) override;
     gl::Error copySubImage(const gl::Context *context,
-                           GLenum target,
-                           size_t level,
+                           const gl::ImageIndex &index,
                            const gl::Offset &destOffset,
                            const gl::Rectangle &sourceArea,
-                           const gl::Framebuffer *source) override;
+                           gl::Framebuffer *source) override;
 
     gl::Error copyTexture(const gl::Context *context,
-                          GLenum target,
-                          size_t level,
+                          const gl::ImageIndex &index,
                           GLenum internalFormat,
                           GLenum type,
                           size_t sourceLevel,
                           bool unpackFlipY,
                           bool unpackPremultiplyAlpha,
                           bool unpackUnmultiplyAlpha,
                           const gl::Texture *source) override;
     gl::Error copySubTexture(const gl::Context *context,
-                             GLenum target,
-                             size_t level,
+                             const gl::ImageIndex &index,
                              const gl::Offset &destOffset,
                              size_t sourceLevel,
                              const gl::Rectangle &sourceArea,
                              bool unpackFlipY,
                              bool unpackPremultiplyAlpha,
                              bool unpackUnmultiplyAlpha,
                              const gl::Texture *source) override;
     gl::Error copyCompressedTexture(const gl::Context *context, const gl::Texture *source) override;
 
     gl::Error setStorage(const gl::Context *context,
-                         GLenum target,
+                         gl::TextureType type,
                          size_t levels,
                          GLenum internalFormat,
                          const gl::Extents &size) override;
 
     gl::Error bindTexImage(const gl::Context *context, egl::Surface *surface) override;
     gl::Error releaseTexImage(const gl::Context *context) override;
 
     gl::Error setEGLImageTarget(const gl::Context *context,
-                                GLenum target,
+                                gl::TextureType type,
                                 egl::Image *image) override;
 
     gl::Error getRenderTarget(const gl::Context *context,
                               const gl::ImageIndex &index,
                               RenderTargetD3D **outRT) override;
 
     gl::ImageIndexIterator imageIterator() const override;
     gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
@@ -336,95 +328,87 @@ class TextureD3D_Cube : public TextureD3
     ImageD3D *getImage(const gl::ImageIndex &index) const override;
     GLsizei getLayerCount(int level) const override;
 
     GLenum getInternalFormat(GLint level, GLint layer) const;
     bool isDepth(GLint level, GLint layer) const;
     bool isSRGB(GLint level, GLint layer) const;
 
     gl::Error setImage(const gl::Context *context,
-                       GLenum target,
-                       size_t level,
+                       const gl::ImageIndex &index,
                        GLenum internalFormat,
                        const gl::Extents &size,
                        GLenum format,
                        GLenum type,
                        const gl::PixelUnpackState &unpack,
                        const uint8_t *pixels) override;
     gl::Error setSubImage(const gl::Context *context,
-                          GLenum target,
-                          size_t level,
+                          const gl::ImageIndex &index,
                           const gl::Box &area,
                           GLenum format,
                           GLenum type,
                           const gl::PixelUnpackState &unpack,
                           const uint8_t *pixels) override;
 
     gl::Error setCompressedImage(const gl::Context *context,
-                                 GLenum target,
-                                 size_t level,
+                                 const gl::ImageIndex &index,
                                  GLenum internalFormat,
                                  const gl::Extents &size,
                                  const gl::PixelUnpackState &unpack,
                                  size_t imageSize,
                                  const uint8_t *pixels) override;
     gl::Error setCompressedSubImage(const gl::Context *context,
-                                    GLenum target,
-                                    size_t level,
+                                    const gl::ImageIndex &index,
                                     const gl::Box &area,
                                     GLenum format,
                                     const gl::PixelUnpackState &unpack,
                                     size_t imageSize,
                                     const uint8_t *pixels) override;
 
     gl::Error copyImage(const gl::Context *context,
-                        GLenum target,
-                        size_t level,
+                        const gl::ImageIndex &index,
                         const gl::Rectangle &sourceArea,
                         GLenum internalFormat,
-                        const gl::Framebuffer *source) override;
+                        gl::Framebuffer *source) override;
     gl::Error copySubImage(const gl::Context *context,
-                           GLenum target,
-                           size_t level,
+                           const gl::ImageIndex &index,
                            const gl::Offset &destOffset,
                            const gl::Rectangle &sourceArea,
-                           const gl::Framebuffer *source) override;
+                           gl::Framebuffer *source) override;
 
     gl::Error copyTexture(const gl::Context *context,
-                          GLenum target,
-                          size_t level,
+                          const gl::ImageIndex &index,
                           GLenum internalFormat,
                           GLenum type,
                           size_t sourceLevel,
                           bool unpackFlipY,
                           bool unpackPremultiplyAlpha,
                           bool unpackUnmultiplyAlpha,
                           const gl::Texture *source) override;
     gl::Error copySubTexture(const gl::Context *context,
-                             GLenum target,
-                             size_t level,
+                             const gl::ImageIndex &index,
                              const gl::Offset &destOffset,
                              size_t sourceLevel,
                              const gl::Rectangle &sourceArea,
                              bool unpackFlipY,
                              bool unpackPremultiplyAlpha,
                              bool unpackUnmultiplyAlpha,
                              const gl::Texture *source) override;
 
     gl::Error setStorage(const gl::Context *context,
-                         GLenum target,
+                         gl::TextureType type,
                          size_t levels,
                          GLenum internalFormat,
                          const gl::Extents &size) override;
 
     gl::Error bindTexImage(const gl::Context *context, egl::Surface *surface) override;
     gl::Error releaseTexImage(const gl::Context *context) override;
 
     gl::Error setEGLImageTarget(const gl::Context *context,
-                                GLenum target,
+                                gl::TextureType type,
                                 egl::Image *image) override;
 
     gl::Error getRenderTarget(const gl::Context *context,
                               const gl::ImageIndex &index,
                               RenderTargetD3D **outRT) override;
 
     gl::ImageIndexIterator imageIterator() const override;
     gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
@@ -473,74 +457,68 @@ class TextureD3D_3D : public TextureD3D
 
     GLsizei getWidth(GLint level) const;
     GLsizei getHeight(GLint level) const;
     GLsizei getDepth(GLint level) const;
     GLenum getInternalFormat(GLint level) const;
     bool isDepth(GLint level) const;
 
     gl::Error setImage(const gl::Context *context,
-                       GLenum target,
-                       size_t level,
+                       const gl::ImageIndex &index,
                        GLenum internalFormat,
                        const gl::Extents &size,
                        GLenum format,
                        GLenum type,
                        const gl::PixelUnpackState &unpack,
                        const uint8_t *pixels) override;
     gl::Error setSubImage(const gl::Context *context,
-                          GLenum target,
-                          size_t level,
+                          const gl::ImageIndex &index,
                           const gl::Box &area,
                           GLenum format,
                           GLenum type,
                           const gl::PixelUnpackState &unpack,
                           const uint8_t *pixels) override;
 
     gl::Error setCompressedImage(const gl::Context *context,
-                                 GLenum target,
-                                 size_t level,
+                                 const gl::ImageIndex &index,
                                  GLenum internalFormat,
                                  const gl::Extents &size,
                                  const gl::PixelUnpackState &unpack,
                                  size_t imageSize,
                                  const uint8_t *pixels) override;
     gl::Error setCompressedSubImage(const gl::Context *context,
-                                    GLenum target,
-                                    size_t level,
+                                    const gl::ImageIndex &index,
                                     const gl::Box &area,
                                     GLenum format,
                                     const gl::PixelUnpackState &unpack,
                                     size_t imageSize,
                                     const uint8_t *pixels) override;
 
     gl::Error copyImage(const gl::Context *context,
-                        GLenum target,
-                        size_t level,
+                        const gl::ImageIndex &index,
                         const gl::Rectangle &sourceArea,
                         GLenum internalFormat,
-                        const gl::Framebuffer *source) override;
+                        gl::Framebuffer *source) override;
     gl::Error copySubImage(const gl::Context *context,
-                           GLenum target,
-                           size_t level,
+                           const gl::ImageIndex &index,
                            const gl::Offset &destOffset,
                            const gl::Rectangle &sourceArea,
-                           const gl::Framebuffer *source) override;
+                           gl::Framebuffer *source) override;
 
     gl::Error setStorage(const gl::Context *context,
-                         GLenum target,
+                         gl::TextureType type,
                          size_t levels,
                          GLenum internalFormat,
                          const gl::Extents &size) override;
 
     gl::Error bindTexImage(const gl::Context *context, egl::Surface *surface) override;
     gl::Error releaseTexImage(const gl::Context *context) override;
 
     gl::Error setEGLImageTarget(const gl::Context *context,
-                                GLenum target,
+                                gl::TextureType type,
                                 egl::Image *image) override;
 
     gl::Error getRenderTarget(const gl::Context *context,
                               const gl::ImageIndex &index,
                               RenderTargetD3D **outRT) override;
 
     gl::ImageIndexIterator imageIterator() const override;
     gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
@@ -587,74 +565,68 @@ class TextureD3D_2DArray : public Textur
     GLsizei getLayerCount(int level) const override;
 
     GLsizei getWidth(GLint level) const;
     GLsizei getHeight(GLint level) const;
     GLenum getInternalFormat(GLint level) const;
     bool isDepth(GLint level) const;
 
     gl::Error setImage(const gl::Context *context,
-                       GLenum target,
-                       size_t level,
+                       const gl::ImageIndex &index,
                        GLenum internalFormat,
                        const gl::Extents &size,
                        GLenum format,
                        GLenum type,
                        const gl::PixelUnpackState &unpack,
                        const uint8_t *pixels) override;
     gl::Error setSubImage(const gl::Context *context,
-                          GLenum target,
-                          size_t level,
+                          const gl::ImageIndex &index,
                           const gl::Box &area,
                           GLenum format,
                           GLenum type,
                           const gl::PixelUnpackState &unpack,
                           const uint8_t *pixels) override;
 
     gl::Error setCompressedImage(const gl::Context *context,
-                                 GLenum target,
-                                 size_t level,
+                                 const gl::ImageIndex &index,
                                  GLenum internalFormat,
                                  const gl::Extents &size,
                                  const gl::PixelUnpackState &unpack,
                                  size_t imageSize,
                                  const uint8_t *pixels) override;
     gl::Error setCompressedSubImage(const gl::Context *context,
-                                    GLenum target,
-                                    size_t level,
+                                    const gl::ImageIndex &index,
                                     const gl::Box &area,
                                     GLenum format,
                                     const gl::PixelUnpackState &unpack,
                                     size_t imageSize,
                                     const uint8_t *pixels) override;
 
     gl::Error copyImage(const gl::Context *context,
-                        GLenum target,
-                        size_t level,
+                        const gl::ImageIndex &index,
                         const gl::Rectangle &sourceArea,
                         GLenum internalFormat,
-                        const gl::Framebuffer *source) override;
+                        gl::Framebuffer *source) override;
     gl::Error copySubImage(const gl::Context *context,
-                           GLenum target,
-                           size_t level,
+                           const gl::ImageIndex &index,
                            const gl::Offset &destOffset,
                            const gl::Rectangle &sourceArea,
-                           const gl::Framebuffer *source) override;
+                           gl::Framebuffer *source) override;
 
     gl::Error setStorage(const gl::Context *context,
-                         GLenum target,
+                         gl::TextureType type,
                          size_t levels,
                          GLenum internalFormat,
                          const gl::Extents &size) override;
 
     gl::Error bindTexImage(const gl::Context *context, egl::Surface *surface) override;
     gl::Error releaseTexImage(const gl::Context *context) override;
 
     gl::Error setEGLImageTarget(const gl::Context *context,
-                                GLenum target,
+                                gl::TextureType type,
                                 egl::Image *image) override;
 
     gl::Error getRenderTarget(const gl::Context *context,
                               const gl::ImageIndex &index,
                               RenderTargetD3D **outRT) override;
 
     gl::ImageIndexIterator imageIterator() const override;
     gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
@@ -698,79 +670,73 @@ class TextureD3D_External : public Textu
   public:
     TextureD3D_External(const gl::TextureState &data, RendererD3D *renderer);
     ~TextureD3D_External() override;
 
     ImageD3D *getImage(const gl::ImageIndex &index) const override;
     GLsizei getLayerCount(int level) const override;
 
     gl::Error setImage(const gl::Context *context,
-                       GLenum target,
-                       size_t level,
+                       const gl::ImageIndex &index,
                        GLenum internalFormat,
                        const gl::Extents &size,
                        GLenum format,
                        GLenum type,
                        const gl::PixelUnpackState &unpack,
                        const uint8_t *pixels) override;
     gl::Error setSubImage(const gl::Context *context,
-                          GLenum target,
-                          size_t level,
+                          const gl::ImageIndex &index,
                           const gl::Box &area,
                           GLenum format,
                           GLenum type,
                           const gl::PixelUnpackState &unpack,
                           const uint8_t *pixels) override;
 
     gl::Error setCompressedImage(const gl::Context *context,
-                                 GLenum target,
-                                 size_t level,
+                                 const gl::ImageIndex &index,
                                  GLenum internalFormat,
                                  const gl::Extents &size,
                                  const gl::PixelUnpackState &unpack,
                                  size_t imageSize,
                                  const uint8_t *pixels) override;
     gl::Error setCompressedSubImage(const gl::Context *context,
-                                    GLenum target,
-                                    size_t level,
+                                    const gl::ImageIndex &index,
                                     const gl::Box &area,
                                     GLenum format,
                                     const gl::PixelUnpackState &unpack,
                                     size_t imageSize,
                                     const uint8_t *pixels) override;
 
     gl::Error copyImage(const gl::Context *context,
-                        GLenum target,
-                        size_t level,
+                        const gl::ImageIndex &index,
                         const gl::Rectangle &sourceArea,
                         GLenum internalFormat,
-                        const gl::Framebuffer *source) override;
+                        gl::Framebuffer *source) override;
     gl::Error copySubImage(const gl::Context *context,
-                           GLenum target,
-                           size_t level,
+                           const gl::ImageIndex &index,
                            const gl::Offset &destOffset,
                            const gl::Rectangle &sourceArea,
-                           const gl::Framebuffer *source) override;
+                           gl::Framebuffer *source) override;
 
     gl::Error setStorage(const gl::Context *context,
-                         GLenum target,
+                         gl::TextureType type,
                          size_t levels,
                          GLenum internalFormat,
                          const gl::Extents &size) override;
 
     gl::Error setImageExternal(const gl::Context *context,
-                               GLenum target,
+                               gl::TextureType type,
                                egl::Stream *stream,
                                const egl::Stream::GLTextureDescription &desc) override;
 
     gl::Error bindTexImage(const gl::Context *context, egl::Surface *surface) override;
     gl::Error releaseTexImage(const gl::Context *context) override;
 
     gl::Error setEGLImageTarget(const gl::Context *context,
-                                GLenum target,
+                                gl::TextureType type,
                                 egl::Image *image) override;
 
     gl::Error getRenderTarget(const gl::Context *context,
                               const gl::ImageIndex &index,
                               RenderTargetD3D **outRT) override;
 
     gl::ImageIndexIterator imageIterator() const override;
     gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
@@ -795,75 +761,69 @@ class TextureD3D_External : public Textu
 class TextureD3D_2DMultisample : public TextureD3D
 {
   public:
     TextureD3D_2DMultisample(const gl::TextureState &data, RendererD3D *renderer);
     ~TextureD3D_2DMultisample() override;
 
     ImageD3D *getImage(const gl::ImageIndex &index) const override;
     gl::Error setImage(const gl::Context *context,
-                       GLenum target,
-                       size_t level,
+                       const gl::ImageIndex &index,
                        GLenum internalFormat,
                        const gl::Extents &size,
                        GLenum format,
                        GLenum type,
                        const gl::PixelUnpackState &unpack,
                        const uint8_t *pixels) override;
     gl::Error setSubImage(const gl::Context *context,
-                          GLenum target,
-                          size_t level,
+                          const gl::ImageIndex &index,
                           const gl::Box &area,
                           GLenum format,
                           GLenum type,
                           const gl::PixelUnpackState &unpack,
                           const uint8_t *pixels) override;
 
     gl::Error setCompressedImage(const gl::Context *context,
-                                 GLenum target,
-                                 size_t level,
+                                 const gl::ImageIndex &index,
                                  GLenum internalFormat,
                                  const gl::Extents &size,
                                  const gl::PixelUnpackState &unpack,
                                  size_t imageSize,
                                  const uint8_t *pixels) override;
     gl::Error setCompressedSubImage(const gl::Context *context,
-                                    GLenum target,
-                                    size_t level,
+                                    const gl::ImageIndex &index,
                                     const gl::Box &area,
                                     GLenum format,
                                     const gl::PixelUnpackState &unpack,
                                     size_t imageSize,
                                     const uint8_t *pixels) override;
 
     gl::Error copyImage(const gl::Context *context,
-                        GLenum target,
-                        size_t level,
+                        const gl::ImageIndex &index,
                         const gl::Rectangle &sourceArea,
                         GLenum internalFormat,
-                        const gl::Framebuffer *source) override;
+                        gl::Framebuffer *source) override;
     gl::Error copySubImage(const gl::Context *context,
-                           GLenum target,
-                           size_t level,
+                           const gl::ImageIndex &index,
                            const gl::Offset &destOffset,
                            const gl::Rectangle &sourceArea,
-                           const gl::Framebuffer *source) override;
+                           gl::Framebuffer *source) override;
 
     gl::Error setStorageMultisample(const gl::Context *context,
-                                    GLenum target,
+                                    gl::TextureType type,
                                     GLsizei samples,
                                     GLint internalFormat,
                                     const gl::Extents &size,
                                     bool fixedSampleLocations) override;
 
     gl::Error bindTexImage(const gl::Context *context, egl::Surface *surface) override;
     gl::Error releaseTexImage(const gl::Context *context) override;
 
     gl::Error setEGLImageTarget(const gl::Context *context,
-                                GLenum target,
+                                gl::TextureType type,
                                 egl::Image *image) override;
 
     gl::Error getRenderTarget(const gl::Context *context,
                               const gl::ImageIndex &index,
                               RenderTargetD3D **outRT) override;
 
     gl::ImageIndexIterator imageIterator() const override;
     gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureStorage.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureStorage.h
@@ -18,26 +18,31 @@
 namespace gl
 {
 class Context;
 struct ImageIndex;
 struct Box;
 struct PixelUnpackState;
 }  // namespace gl
 
+namespace angle
+{
+class Subject;
+}  // namespace angle
+
 namespace rx
 {
 class SwapChainD3D;
 class RenderTargetD3D;
 class ImageD3D;
 
 class TextureStorage : angle::NonCopyable
 {
   public:
-    TextureStorage() {}
+    TextureStorage() : mSubject(nullptr) {}
     virtual ~TextureStorage() {}
 
     virtual gl::Error onDestroy(const gl::Context *context);
 
     virtual int getTopLevel() const = 0;
     virtual bool isRenderTarget() const = 0;
     virtual bool isManaged() const = 0;
     virtual bool supportsNativeMipmapFunction() const = 0;
@@ -57,26 +62,37 @@ class TextureStorage : angle::NonCopyabl
                               const gl::Box *destBox,
                               GLenum type,
                               const gl::PixelUnpackState &unpack,
                               const uint8_t *pixelData) = 0;
 
     // This is a no-op for most implementations of TextureStorage. Some (e.g. TextureStorage11_2D) might override it.
     virtual gl::Error useLevelZeroWorkaroundTexture(const gl::Context *context,
                                                     bool useLevelZeroTexture);
+
+    // Only used for D3D11.
+    void setSubject(const angle::Subject *subject);
+
+  protected:
+    const angle::Subject *mSubject;
 };
 
 inline gl::Error TextureStorage::onDestroy(const gl::Context *context)
 {
     return gl::NoError();
 }
 
 inline gl::Error TextureStorage::useLevelZeroWorkaroundTexture(const gl::Context *context,
                                                                bool useLevelZeroTexture)
 {
     return gl::NoError();
 }
 
+inline void TextureStorage::setSubject(const angle::Subject *subject)
+{
+    mSubject = subject;
+}
+
 using TexStoragePointer = angle::UniqueObjectPointer<TextureStorage, gl::Context>;
 
 }  // namespace rx
 
 #endif // LIBANGLE_RENDERER_D3D_TEXTURESTORAGE_H_
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.cpp
@@ -87,17 +87,17 @@ gl::Error VertexBufferInterface::setBuff
     }
 
     return mVertexBuffer->setBufferSize(size);
 }
 
 gl::ErrorOrResult<unsigned int> VertexBufferInterface::getSpaceRequired(
     const gl::VertexAttribute &attrib,
     const gl::VertexBinding &binding,
-    GLsizei count,
+    size_t count,
     GLsizei instances) const
 {
     unsigned int spaceRequired = 0;
     ANGLE_TRY_RESULT(mFactory->getVertexSpaceRequired(attrib, binding, count, instances),
                      spaceRequired);
 
     // Align to 16-byte boundary
     unsigned int alignedSpaceRequired = roundUp(spaceRequired, 16u);
@@ -150,17 +150,17 @@ gl::Error StreamingVertexBufferInterface
 
     return gl::NoError();
 }
 
 gl::Error StreamingVertexBufferInterface::storeDynamicAttribute(const gl::VertexAttribute &attrib,
                                                                 const gl::VertexBinding &binding,
                                                                 GLenum currentValueType,
                                                                 GLint start,
-                                                                GLsizei count,
+                                                                size_t count,
                                                                 GLsizei instances,
                                                                 unsigned int *outStreamOffset,
                                                                 const uint8_t *sourceData)
 {
     unsigned int spaceRequired = 0;
     ANGLE_TRY_RESULT(getSpaceRequired(attrib, binding, count, instances), spaceRequired);
 
     // Protect against integer overflow
@@ -185,17 +185,17 @@ gl::Error StreamingVertexBufferInterface
 
     mWritePosition += spaceRequired;
 
     return gl::NoError();
 }
 
 gl::Error StreamingVertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attrib,
                                                              const gl::VertexBinding &binding,
-                                                             GLsizei count,
+                                                             size_t count,
                                                              GLsizei instances)
 {
     unsigned int requiredSpace = 0;
     ANGLE_TRY_RESULT(mFactory->getVertexSpaceRequired(attrib, binding, count, instances),
                      requiredSpace);
 
     // Align to 16-byte boundary
     auto alignedRequiredSpace = rx::CheckedRoundUp(requiredSpace, 16u);
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.h
@@ -40,17 +40,17 @@ class VertexBuffer : angle::NonCopyable
     virtual gl::Error initialize(unsigned int size, bool dynamicUsage) = 0;
 
     // Warning: you should ensure binding really matches attrib.bindingIndex before using this
     // function.
     virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib,
                                             const gl::VertexBinding &binding,
                                             GLenum currentValueType,
                                             GLint start,
-                                            GLsizei count,
+                                            size_t count,
                                             GLsizei instances,
                                             unsigned int offset,
                                             const uint8_t *sourceData) = 0;
 
     virtual unsigned int getBufferSize() const = 0;
     virtual gl::Error setBufferSize(unsigned int size) = 0;
     virtual gl::Error discard() = 0;
 
@@ -88,41 +88,41 @@ class VertexBufferInterface : angle::Non
 
   protected:
     gl::Error discard();
 
     gl::Error setBufferSize(unsigned int size);
 
     gl::ErrorOrResult<unsigned int> getSpaceRequired(const gl::VertexAttribute &attrib,
                                                      const gl::VertexBinding &binding,
-                                                     GLsizei count,
+                                                     size_t count,
                                                      GLsizei instances) const;
     BufferFactoryD3D *const mFactory;
     VertexBuffer *mVertexBuffer;
     bool mDynamic;
 };
 
 class StreamingVertexBufferInterface : public VertexBufferInterface
 {
   public:
     StreamingVertexBufferInterface(BufferFactoryD3D *factory, std::size_t initialSize);
     ~StreamingVertexBufferInterface() override;
 
     gl::Error storeDynamicAttribute(const gl::VertexAttribute &attrib,
                                     const gl::VertexBinding &binding,
                                     GLenum currentValueType,
                                     GLint start,
-                                    GLsizei count,
+                                    size_t count,
                                     GLsizei instances,
                                     unsigned int *outStreamOffset,
                                     const uint8_t *sourceData);
 
     gl::Error reserveVertexSpace(const gl::VertexAttribute &attribute,
                                  const gl::VertexBinding &binding,
-                                 GLsizei count,
+                                 size_t count,
                                  GLsizei instances);
 
   private:
     gl::Error reserveSpace(unsigned int size);
 
     unsigned int mWritePosition;
     unsigned int mReservedSpace;
 };
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.cpp
@@ -148,17 +148,17 @@ VertexStorageType ClassifyAttributeStora
 {
     // If attribute is disabled, we use the current value.
     if (!attrib.enabled)
     {
         return VertexStorageType::CURRENT_VALUE;
     }
 
     // If specified with immediate data, we must use dynamic storage.
-    auto *buffer = binding.getBuffer().get();
+    gl::Buffer *buffer = binding.getBuffer().get();
     if (!buffer)
     {
         return VertexStorageType::DYNAMIC;
     }
 
     // Check if the buffer supports direct storage.
     if (DirectStoragePossible(attrib, binding))
     {
@@ -387,17 +387,17 @@ gl::Error VertexDataManager::StoreStatic
     return gl::NoError();
 }
 
 gl::Error VertexDataManager::storeDynamicAttribs(
     const gl::Context *context,
     std::vector<TranslatedAttribute> *translatedAttribs,
     const gl::AttributesMask &dynamicAttribsMask,
     GLint start,
-    GLsizei count,
+    size_t count,
     GLsizei instances)
 {
     // Instantiating this class will ensure the streaming buffer is never left mapped.
     class StreamingBufferUnmapper final : NonCopyable
     {
       public:
         StreamingBufferUnmapper(StreamingVertexBufferInterface *streamingBuffer)
             : mStreamingBuffer(streamingBuffer)
@@ -429,51 +429,52 @@ gl::Error VertexDataManager::storeDynami
 
     return gl::NoError();
 }
 
 void VertexDataManager::PromoteDynamicAttribs(
     const gl::Context *context,
     const std::vector<TranslatedAttribute> &translatedAttribs,
     const gl::AttributesMask &dynamicAttribsMask,
-    GLsizei count)
+    size_t count)
 {
     for (auto attribIndex : dynamicAttribsMask)
     {
         const auto &dynamicAttrib = translatedAttribs[attribIndex];
         ASSERT(dynamicAttrib.attribute && dynamicAttrib.binding);
         const auto &binding       = *dynamicAttrib.binding;
 
         gl::Buffer *buffer = binding.getBuffer().get();
         if (buffer)
         {
+            // Note: this multiplication can overflow. It should not be a security problem.
             BufferD3D *bufferD3D = GetImplAs<BufferD3D>(buffer);
             size_t typeSize      = ComputeVertexAttributeTypeSize(*dynamicAttrib.attribute);
-            bufferD3D->promoteStaticUsage(context, count * static_cast<int>(typeSize));
+            bufferD3D->promoteStaticUsage(context, count * typeSize);
         }
     }
 }
 
 gl::Error VertexDataManager::reserveSpaceForAttrib(const TranslatedAttribute &translatedAttrib,
                                                    GLint start,
-                                                   GLsizei count,
+                                                   size_t count,
                                                    GLsizei instances) const
 {
     ASSERT(translatedAttrib.attribute && translatedAttrib.binding);
     const auto &attrib  = *translatedAttrib.attribute;
     const auto &binding = *translatedAttrib.binding;
 
     ASSERT(!DirectStoragePossible(attrib, binding));
 
     gl::Buffer *buffer   = binding.getBuffer().get();
     BufferD3D *bufferD3D = buffer ? GetImplAs<BufferD3D>(buffer) : nullptr;
     ASSERT(!bufferD3D || bufferD3D->getStaticVertexBuffer(attrib, binding) == nullptr);
 
-    size_t totalCount = gl::ComputeVertexBindingElementCount(
-        binding.getDivisor(), static_cast<size_t>(count), static_cast<size_t>(instances));
+    size_t totalCount = gl::ComputeVertexBindingElementCount(binding.getDivisor(), count,
+                                                             static_cast<size_t>(instances));
     // TODO(jiajia.qin@intel.com): force the index buffer to clamp any out of range indices instead
     // of invalid operation here.
     if (bufferD3D)
     {
         // Vertices do not apply the 'start' offset when the divisor is non-zero even when doing
         // a non-instanced draw call
         GLint firstVertexIndex = binding.getDivisor() > 0 ? 0 : start;
         int64_t maxVertexCount =
@@ -481,25 +482,24 @@ gl::Error VertexDataManager::reserveSpac
         int elementsInBuffer =
             ElementsInBuffer(attrib, binding, static_cast<unsigned int>(bufferD3D->getSize()));
 
         if (maxVertexCount > elementsInBuffer)
         {
             return gl::InvalidOperation() << "Vertex buffer is not big enough for the draw call.";
         }
     }
-    return mStreamingBuffer->reserveVertexSpace(attrib, binding, static_cast<GLsizei>(totalCount),
-                                                instances);
+    return mStreamingBuffer->reserveVertexSpace(attrib, binding, totalCount, instances);
 }
 
 gl::Error VertexDataManager::storeDynamicAttrib(const gl::Context *context,
                                                 TranslatedAttribute *translated,
                                                 GLint start,
-                                                GLsizei count,
-                                                GLsizei instances)
+                                                size_t count,
+                                                GLsizei instances) const
 {
     ASSERT(translated->attribute && translated->binding);
     const auto &attrib  = *translated->attribute;
     const auto &binding = *translated->binding;
 
     gl::Buffer *buffer = binding.getBuffer().get();
     ASSERT(buffer || attrib.pointer);
     ASSERT(attrib.enabled);
@@ -524,18 +524,18 @@ gl::Error VertexDataManager::storeDynami
         sourceData = static_cast<const uint8_t*>(attrib.pointer);
     }
 
     unsigned int streamOffset = 0;
 
     translated->storage = nullptr;
     ANGLE_TRY_RESULT(mFactory->getVertexSpaceRequired(attrib, binding, 1, 0), translated->stride);
 
-    size_t totalCount = gl::ComputeVertexBindingElementCount(
-        binding.getDivisor(), static_cast<size_t>(count), static_cast<size_t>(instances));
+    size_t totalCount = gl::ComputeVertexBindingElementCount(binding.getDivisor(), count,
+                                                             static_cast<size_t>(instances));
 
     ANGLE_TRY(mStreamingBuffer->storeDynamicAttribute(
         attrib, binding, translated->currentValueType, firstVertexIndex,
         static_cast<GLsizei>(totalCount), instances, &streamOffset, sourceData));
 
     VertexBuffer *vertexBuffer = mStreamingBuffer->getVertexBuffer();
 
     translated->vertexBuffer.set(vertexBuffer);
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.h
@@ -100,24 +100,24 @@ class VertexDataManager : angle::NonCopy
     static void StoreDirectAttrib(TranslatedAttribute *directAttrib);
 
     static gl::Error StoreStaticAttrib(const gl::Context *context, TranslatedAttribute *translated);
 
     gl::Error storeDynamicAttribs(const gl::Context *context,
                                   std::vector<TranslatedAttribute> *translatedAttribs,
                                   const gl::AttributesMask &dynamicAttribsMask,
                                   GLint start,
-                                  GLsizei count,
+                                  size_t count,
                                   GLsizei instances);
 
     // Promote static usage of dynamic buffers.
     static void PromoteDynamicAttribs(const gl::Context *context,
                                       const std::vector<TranslatedAttribute> &translatedAttribs,
                                       const gl::AttributesMask &dynamicAttribsMask,
-                                      GLsizei count);
+                                      size_t count);
 
     gl::Error storeCurrentValue(const gl::VertexAttribCurrentValueData &currentValue,
                                 TranslatedAttribute *translated,
                                 size_t attribIndex);
 
   private:
     struct CurrentValueState
     {
@@ -125,25 +125,25 @@ class VertexDataManager : angle::NonCopy
         ~CurrentValueState();
 
         std::unique_ptr<StreamingVertexBufferInterface> buffer;
         gl::VertexAttribCurrentValueData data;
         size_t offset;
     };
 
     gl::Error reserveSpaceForAttrib(const TranslatedAttribute &translatedAttrib,
-                                    GLsizei count,
                                     GLint start,
+                                    size_t count,
                                     GLsizei instances) const;
 
     gl::Error storeDynamicAttrib(const gl::Context *context,
                                  TranslatedAttribute *translated,
                                  GLint start,
-                                 GLsizei count,
-                                 GLsizei instances);
+                                 size_t count,
+                                 GLsizei instances) const;
 
     BufferFactoryD3D *const mFactory;
 
     std::unique_ptr<StreamingVertexBufferInterface> mStreamingBuffer;
     std::vector<CurrentValueState> mCurrentValueCache;
     gl::AttributesMask mDynamicAttribsMaskCache;
 };
 
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
@@ -1546,17 +1546,17 @@ gl::Error Blit11::copyAndConvert(const T
     ANGLE_TRY(copyAndConvertImpl(source, sourceSubresource, sourceArea, sourceSize, destStaging,
                                  destArea, destSize, scissor, readOffset, writeOffset, copySize,
                                  srcPixelStride, destPixelStride, convertFunction));
 
     // Work around timeouts/TDRs in older NVIDIA drivers.
     if (mRenderer->getWorkarounds().depthStencilBlitExtraCopy)
     {
         D3D11_MAPPED_SUBRESOURCE mapped;
-        deviceContext->Map(destStaging.get(), 0, D3D11_MAP_READ, 0, &mapped);
+        ANGLE_TRY(mRenderer->mapResource(destStaging.get(), 0, D3D11_MAP_READ, 0, &mapped));
         deviceContext->UpdateSubresource(dest.get(), destSubresource, nullptr, mapped.pData,
                                          mapped.RowPitch, mapped.DepthPitch);
         deviceContext->Unmap(destStaging.get(), 0);
     }
     else
     {
         deviceContext->CopySubresourceRegion(dest.get(), destSubresource, 0, 0, 0,
                                              destStaging.get(), 0, nullptr);
@@ -2038,17 +2038,18 @@ gl::ErrorOrResult<TextureHelper11> Blit1
                                  &mResolveDepthPS.getObj());
     stateManager->setRasterizerState(nullptr);
     stateManager->setDepthStencilState(&mDepthStencilState, 0xFFFFFFFF);
     stateManager->setRenderTargets(nullptr, 0, mResolvedDepthDSView.get());
     stateManager->setSimpleBlendState(nullptr);
     stateManager->setSimpleViewport(extents);
 
     // Set the viewport
-    stateManager->setShaderResourceShared(gl::SHADER_FRAGMENT, 0, &depth->getShaderResourceView());
+    stateManager->setShaderResourceShared(gl::ShaderType::Fragment, 0,
+                                          &depth->getShaderResourceView());
 
     // Trigger the blit on the GPU.
     deviceContext->Draw(6, 0);
 
     return mResolvedDepth;
 }
 
 gl::Error Blit11::initResolveDepthOnly(const d3d11::Format &format, const gl::Extents &extents)
@@ -2196,19 +2197,19 @@ gl::ErrorOrResult<TextureHelper11> Blit1
     stateManager->setDrawShaders(&mResolveDepthStencilVS.getObj(), nullptr, pixelShader);
     stateManager->setRasterizerState(nullptr);
     stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF);
     stateManager->setRenderTarget(mResolvedDepthStencilRTView.get(), nullptr);
     stateManager->setSimpleBlendState(nullptr);
 
     // Set the viewport
     stateManager->setSimpleViewport(extents);
-    stateManager->setShaderResourceShared(gl::SHADER_FRAGMENT, 0,
+    stateManager->setShaderResourceShared(gl::ShaderType::Fragment, 0,
                                           &depthStencil->getShaderResourceView());
-    stateManager->setShaderResource(gl::SHADER_FRAGMENT, 1, &mStencilSRV);
+    stateManager->setShaderResource(gl::ShaderType::Fragment, 1, &mStencilSRV);
 
     // Trigger the blit on the GPU.
     deviceContext->Draw(6, 0);
 
     gl::Box copyBox(0, 0, 0, extents.width, extents.height, 1);
 
     TextureHelper11 dest;
     ANGLE_TRY_RESULT(
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
@@ -393,20 +393,16 @@ gl::Error Buffer11::setSubData(const gl:
         if (writeBuffer->getSize() < requiredSize)
         {
             bool preserveData = (offset > 0);
             ANGLE_TRY(writeBuffer->resize(context, requiredSize, preserveData));
         }
 
         ANGLE_TRY(writeBuffer->setData(static_cast<const uint8_t *>(data), offset, size));
         onStorageUpdate(writeBuffer);
-
-        // Notify any vertex arrays that we have dirty data.
-        // TODO(jmadill): Use a more fine grained notification for data updates.
-        mDirectSubject.onStateChange(context, angle::SubjectMessage::STATE_CHANGE);
     }
 
     mSize = std::max(mSize, requiredSize);
     invalidateStaticData(context);
 
     return gl::NoError();
 }
 
@@ -466,19 +462,16 @@ gl::Error Buffer11::copySubData(const gl
     CopyResult copyResult = CopyResult::NOT_RECREATED;
     ANGLE_TRY_RESULT(copyDest->copyFromStorage(context, copySource, sourceOffset, size, destOffset),
                      copyResult);
     onStorageUpdate(copyDest);
 
     mSize = std::max<size_t>(mSize, destOffset + size);
     invalidateStaticData(context);
 
-    // Also notify that direct buffers are dirty.
-    mDirectSubject.onStateChange(context, angle::SubjectMessage::STATE_CHANGE);
-
     return gl::NoError();
 }
 
 gl::Error Buffer11::map(const gl::Context *context, GLenum access, void **mapPtr)
 {
     // GL_OES_mapbuffer uses an enum instead of a bitfield for it's access, convert to a bitfield
     // and call mapRange.
     ASSERT(access == GL_WRITE_ONLY_OES);
@@ -753,17 +746,17 @@ Buffer11::BufferStorage *Buffer11::alloc
         case BUFFER_USAGE_PIXEL_PACK:
             return new PackStorage(mRenderer);
         case BUFFER_USAGE_SYSTEM_MEMORY:
             return new SystemMemoryStorage(mRenderer);
         case BUFFER_USAGE_EMULATED_INDEXED_VERTEX:
             return new EmulatedIndexedStorage(mRenderer);
         case BUFFER_USAGE_INDEX:
         case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK:
-            return new NativeStorage(mRenderer, usage, &mDirectSubject);
+            return new NativeStorage(mRenderer, usage, this);
         default:
             return new NativeStorage(mRenderer, usage, nullptr);
     }
 }
 
 gl::ErrorOrResult<Buffer11::BufferStorage *> Buffer11::getConstantBufferRangeStorage(
     const gl::Context *context,
     GLintptr offset,
@@ -914,37 +907,23 @@ bool Buffer11::supportsDirectBinding() c
     // Do not support direct buffers for dynamic data. The streaming buffer
     // offers better performance for data which changes every frame.
     return (mUsage == D3DBufferUsage::STATIC);
 }
 
 void Buffer11::initializeStaticData(const gl::Context *context)
 {
     BufferD3D::initializeStaticData(context);
-
-    // Notify when static data changes.
-    mStaticSubject.onStateChange(context, angle::SubjectMessage::STATE_CHANGE);
+    onStateChange(context, angle::SubjectMessage::STORAGE_CHANGED);
 }
 
 void Buffer11::invalidateStaticData(const gl::Context *context)
 {
     BufferD3D::invalidateStaticData(context);
-
-    // Notify when static data changes.
-    mStaticSubject.onStateChange(context, angle::SubjectMessage::STATE_CHANGE);
-}
-
-angle::Subject *Buffer11::getStaticSubject()
-{
-    return &mStaticSubject;
-}
-
-angle::Subject *Buffer11::getDirectSubject()
-{
-    return &mDirectSubject;
+    onStateChange(context, angle::SubjectMessage::STORAGE_CHANGED);
 }
 
 void Buffer11::onCopyStorage(BufferStorage *dest, BufferStorage *source)
 {
     ASSERT(source && mLatestBufferStorage);
     dest->setDataRevision(source->getDataRevision());
 
     // Only update the latest buffer storage if our usage index is lower. See comment in header.
@@ -1104,17 +1083,17 @@ gl::Error Buffer11::NativeStorage::resiz
     mBufferSize = bufferDesc.ByteWidth;
 
     // Free the SRVs.
     clearSRVs();
 
     // Notify that the storage has changed.
     if (mOnStorageChanged)
     {
-        mOnStorageChanged->onStateChange(context, angle::SubjectMessage::STATE_CHANGE);
+        mOnStorageChanged->onStateChange(context, angle::SubjectMessage::STORAGE_CHANGED);
     }
 
     return gl::NoError();
 }
 
 // static
 void Buffer11::NativeStorage::FillBufferDesc(D3D11_BUFFER_DESC *bufferDesc,
                                              Renderer11 *renderer,
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
@@ -99,22 +99,16 @@ class Buffer11 : public BufferD3D
     gl::Error mapRange(const gl::Context *context,
                        size_t offset,
                        size_t length,
                        GLbitfield access,
                        void **mapPtr) override;
     gl::Error unmap(const gl::Context *context, GLboolean *result) override;
     gl::Error markTransformFeedbackUsage(const gl::Context *context) override;
 
-    // We use two set of dirty events. Static buffers are marked dirty whenever
-    // data changes, because they must be re-translated. Direct buffers only need to be
-    // updated when the underlying ID3D11Buffer pointer changes - hopefully far less often.
-    angle::Subject *getStaticSubject();
-    angle::Subject *getDirectSubject();
-
   private:
     class BufferStorage;
     class EmulatedIndexedStorage;
     class NativeStorage;
     class PackStorage;
     class SystemMemoryStorage;
 
     struct ConstantBufferCacheEntry
@@ -174,16 +168,13 @@ class Buffer11 : public BufferD3D
 
     // Cache of D3D11 constant buffer for specific ranges of buffer data.
     // This is used to emulate UBO ranges on 11.0 devices.
     // Constant buffers are indexed by there start offset.
     typedef std::map<GLintptr /*offset*/, ConstantBufferCacheEntry> ConstantBufferCache;
     ConstantBufferCache mConstantBufferRangeStoragesCache;
     size_t mConstantBufferStorageAdditionalSize;
     unsigned int mMaxConstantBufferLruCount;
-
-    angle::Subject mStaticSubject;
-    angle::Subject mDirectSubject;
 };
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
@@ -16,25 +16,103 @@
 #include "libANGLE/renderer/d3d/ProgramD3D.h"
 #include "libANGLE/renderer/d3d/RenderbufferD3D.h"
 #include "libANGLE/renderer/d3d/SamplerD3D.h"
 #include "libANGLE/renderer/d3d/ShaderD3D.h"
 #include "libANGLE/renderer/d3d/TextureD3D.h"
 #include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
 #include "libANGLE/renderer/d3d/d3d11/Fence11.h"
 #include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h"
 #include "libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h"
 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
 #include "libANGLE/renderer/d3d/d3d11/StateManager11.h"
 #include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h"
 #include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
 
 namespace rx
 {
 
+namespace
+{
+bool DrawCallHasStreamingVertexArrays(const gl::Context *context, GLenum mode)
+{
+    const gl::State &glState           = context->getGLState();
+    const gl::VertexArray *vertexArray = glState.getVertexArray();
+    VertexArray11 *vertexArray11       = GetImplAs<VertexArray11>(vertexArray);
+    // Direct drawing doesn't support dynamic attribute storage since it needs the first and count
+    // to translate when applyVertexBuffer. GL_LINE_LOOP and GL_TRIANGLE_FAN are not supported
+    // either since we need to simulate them in D3D.
+    if (vertexArray11->hasActiveDynamicAttrib(context) || mode == GL_LINE_LOOP ||
+        mode == GL_TRIANGLE_FAN)
+    {
+        return true;
+    }
+
+    ProgramD3D *programD3D = GetImplAs<ProgramD3D>(glState.getProgram());
+    if (InstancedPointSpritesActive(programD3D, mode))
+    {
+        return true;
+    }
+
+    return false;
+}
+
+bool DrawCallHasStreamingElementArray(const gl::Context *context, GLenum srcType)
+{
+    const gl::State &glState       = context->getGLState();
+    gl::Buffer *elementArrayBuffer = glState.getVertexArray()->getElementArrayBuffer().get();
+
+    bool primitiveRestartWorkaround =
+        UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), srcType);
+    const GLenum dstType = (srcType == GL_UNSIGNED_INT || primitiveRestartWorkaround)
+                               ? GL_UNSIGNED_INT
+                               : GL_UNSIGNED_SHORT;
+
+    // Not clear where the offset comes from here.
+    switch (ClassifyIndexStorage(glState, elementArrayBuffer, srcType, dstType, 0))
+    {
+        case IndexStorageType::Dynamic:
+            return true;
+        case IndexStorageType::Direct:
+            return false;
+        case IndexStorageType::Static:
+        {
+            BufferD3D *bufferD3D                     = GetImplAs<BufferD3D>(elementArrayBuffer);
+            StaticIndexBufferInterface *staticBuffer = bufferD3D->getStaticIndexBuffer();
+            return (staticBuffer->getBufferSize() == 0 || staticBuffer->getIndexType() != dstType);
+        }
+        default:
+            UNREACHABLE();
+            return true;
+    }
+}
+
+template <typename IndirectBufferT>
+gl::Error ReadbackIndirectBuffer(const gl::Context *context,
+                                 const void *indirect,
+                                 const IndirectBufferT **bufferPtrOut)
+{
+    const gl::State &glState       = context->getGLState();
+    gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect);
+    ASSERT(drawIndirectBuffer);
+    Buffer11 *storage = GetImplAs<Buffer11>(drawIndirectBuffer);
+    uintptr_t offset  = reinterpret_cast<uintptr_t>(indirect);
+
+    const uint8_t *bufferData = nullptr;
+    ANGLE_TRY(storage->getData(context, &bufferData));
+    ASSERT(bufferData);
+
+    *bufferPtrOut = reinterpret_cast<const IndirectBufferT *>(bufferData + offset);
+    return gl::NoError();
+}
+
+}  // anonymous namespace
+
 Context11::Context11(const gl::ContextState &state, Renderer11 *renderer)
     : ContextImpl(state), mRenderer(renderer)
 {
 }
 
 Context11::~Context11()
 {
 }
@@ -68,31 +146,30 @@ ProgramImpl *Context11::createProgram(co
 
 FramebufferImpl *Context11::createFramebuffer(const gl::FramebufferState &data)
 {
     return new Framebuffer11(data, mRenderer);
 }
 
 TextureImpl *Context11::createTexture(const gl::TextureState &state)
 {
-    switch (state.getTarget())
+    switch (state.getType())
     {
-        case GL_TEXTURE_2D:
+        case gl::TextureType::_2D:
             return new TextureD3D_2D(state, mRenderer);
-        case GL_TEXTURE_CUBE_MAP:
+        case gl::TextureType::CubeMap:
             return new TextureD3D_Cube(state, mRenderer);
-        case GL_TEXTURE_3D:
+        case gl::TextureType::_3D:
             return new TextureD3D_3D(state, mRenderer);
-        case GL_TEXTURE_2D_ARRAY:
+        case gl::TextureType::_2DArray:
             return new TextureD3D_2DArray(state, mRenderer);
-        case GL_TEXTURE_EXTERNAL_OES:
+        case gl::TextureType::External:
             return new TextureD3D_External(state, mRenderer);
-        case GL_TEXTURE_2D_MULTISAMPLE:
+        case gl::TextureType::_2DMultisample:
             return new TextureD3D_2DMultisample(state, mRenderer);
-            break;
         default:
             UNREACHABLE();
     }
 
     return nullptr;
 }
 
 RenderbufferImpl *Context11::createRenderbuffer(const gl::RenderbufferState &state)
@@ -154,78 +231,128 @@ gl::Error Context11::flush(const gl::Con
 
 gl::Error Context11::finish(const gl::Context *context)
 {
     return mRenderer->finish();
 }
 
 gl::Error Context11::drawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count)
 {
-    ANGLE_TRY(prepareForDrawCall(context, mode));
-    return mRenderer->drawArrays(context, mode, first, count, 0);
+    const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
+    ASSERT(!drawCallParams.isDrawElements() && !drawCallParams.isDrawIndirect());
+    ANGLE_TRY(prepareForDrawCall(context, drawCallParams));
+    return mRenderer->drawArrays(context, drawCallParams);
 }
 
 gl::Error Context11::drawArraysInstanced(const gl::Context *context,
                                          GLenum mode,
                                          GLint first,
                                          GLsizei count,
                                          GLsizei instanceCount)
 {
-    ANGLE_TRY(prepareForDrawCall(context, mode));
-    return mRenderer->drawArrays(context, mode, first, count, instanceCount);
+    const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
+    ASSERT(!drawCallParams.isDrawElements() && !drawCallParams.isDrawIndirect());
+    ANGLE_TRY(prepareForDrawCall(context, drawCallParams));
+    return mRenderer->drawArrays(context, drawCallParams);
 }
 
 gl::Error Context11::drawElements(const gl::Context *context,
                                   GLenum mode,
                                   GLsizei count,
                                   GLenum type,
                                   const void *indices)
 {
-    ANGLE_TRY(prepareForDrawCall(context, mode));
-    return mRenderer->drawElements(context, mode, count, type, indices, 0);
+    const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
+    ASSERT(drawCallParams.isDrawElements() && !drawCallParams.isDrawIndirect());
+    ANGLE_TRY(prepareForDrawCall(context, drawCallParams));
+    return mRenderer->drawElements(context, drawCallParams);
 }
 
 gl::Error Context11::drawElementsInstanced(const gl::Context *context,
                                            GLenum mode,
                                            GLsizei count,
                                            GLenum type,
                                            const void *indices,
                                            GLsizei instances)
 {
-    ANGLE_TRY(prepareForDrawCall(context, mode));
-    return mRenderer->drawElements(context, mode, count, type, indices, instances);
+    const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
+    ASSERT(drawCallParams.isDrawElements() && !drawCallParams.isDrawIndirect());
+    ANGLE_TRY(prepareForDrawCall(context, drawCallParams));
+    return mRenderer->drawElements(context, drawCallParams);
 }
 
 gl::Error Context11::drawRangeElements(const gl::Context *context,
                                        GLenum mode,
                                        GLuint start,
                                        GLuint end,
                                        GLsizei count,
                                        GLenum type,
                                        const void *indices)
 {
-    ANGLE_TRY(prepareForDrawCall(context, mode));
-    return mRenderer->drawElements(context, mode, count, type, indices, 0);
+    const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
+    ASSERT(drawCallParams.isDrawElements() && !drawCallParams.isDrawIndirect());
+    ANGLE_TRY(prepareForDrawCall(context, drawCallParams));
+    return mRenderer->drawElements(context, drawCallParams);
 }
 
 gl::Error Context11::drawArraysIndirect(const gl::Context *context,
                                         GLenum mode,
                                         const void *indirect)
 {
-    ANGLE_TRY(prepareForDrawCall(context, mode));
-    return mRenderer->drawArraysIndirect(context, mode, indirect);
+    if (DrawCallHasStreamingVertexArrays(context, mode))
+    {
+        const gl::DrawArraysIndirectCommand *cmd = nullptr;
+        ANGLE_TRY(ReadbackIndirectBuffer(context, indirect, &cmd));
+
+        gl::DrawCallParams drawCallParams(mode, cmd->first, cmd->count, cmd->instanceCount);
+        ANGLE_TRY(prepareForDrawCall(context, drawCallParams));
+        return mRenderer->drawArrays(context, drawCallParams);
+    }
+    else
+    {
+        const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
+        ASSERT(!drawCallParams.isDrawElements() && drawCallParams.isDrawIndirect());
+        ANGLE_TRY(prepareForDrawCall(context, drawCallParams));
+        return mRenderer->drawArraysIndirect(context, drawCallParams);
+    }
 }
 
 gl::Error Context11::drawElementsIndirect(const gl::Context *context,
                                           GLenum mode,
                                           GLenum type,
                                           const void *indirect)
 {
-    ANGLE_TRY(prepareForDrawCall(context, mode));
-    return mRenderer->drawElementsIndirect(context, mode, type, indirect);
+    if (DrawCallHasStreamingVertexArrays(context, mode) ||
+        DrawCallHasStreamingElementArray(context, type))
+    {
+        const gl::DrawElementsIndirectCommand *cmd = nullptr;
+        ANGLE_TRY(ReadbackIndirectBuffer(context, indirect, &cmd));
+
+        const gl::Type &typeInfo = gl::GetTypeInfo(type);
+        const void *indices      = reinterpret_cast<const void *>(
+            static_cast<uintptr_t>(cmd->firstIndex * typeInfo.bytes));
+
+        gl::DrawCallParams drawCallParams(mode, cmd->count, type, indices, cmd->baseVertex,
+                                          cmd->primCount);
+
+        // We must explicitly resolve the index range for the slow-path indirect drawElements to
+        // make sure we are using the correct 'baseVertex'. This parameter does not exist for the
+        // direct drawElements.
+        ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
+
+        ANGLE_TRY(prepareForDrawCall(context, drawCallParams));
+        return mRenderer->drawElements(context, drawCallParams);
+    }
+    else
+    {
+        const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
+        ASSERT(drawCallParams.isDrawElements() && drawCallParams.isDrawIndirect());
+        ANGLE_TRY(prepareForDrawCall(context, drawCallParams));
+        return mRenderer->drawElementsIndirect(context, drawCallParams);
+    }
 }
 
 GLenum Context11::getResetStatus()
 {
     return mRenderer->getResetStatus();
 }
 
 std::string Context11::getVendorString() const
@@ -397,27 +524,26 @@ gl::Error Context11::triggerDrawCallProg
     if (mMemoryProgramCache)
     {
         mMemoryProgramCache->updateProgram(context, program);
     }
 
     return gl::NoError();
 }
 
-gl::Error Context11::prepareForDrawCall(const gl::Context *context, GLenum drawMode)
+gl::Error Context11::prepareForDrawCall(const gl::Context *context,
+                                        const gl::DrawCallParams &drawCallParams)
 {
-    ANGLE_TRY(mRenderer->getStateManager()->updateState(context, drawMode));
+    ANGLE_TRY(mRenderer->getStateManager()->updateState(context, drawCallParams));
     return gl::NoError();
 }
 
 gl::Error Context11::memoryBarrier(const gl::Context *context, GLbitfield barriers)
 {
-    UNIMPLEMENTED();
     return gl::NoError();
 }
 
 gl::Error Context11::memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers)
 {
-    UNIMPLEMENTED();
     return gl::NoError();
 }
 
 }  // namespace rx
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.h
@@ -144,16 +144,17 @@ class Context11 : public ContextImpl
     gl::Error dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) override;
 
     gl::Error memoryBarrier(const gl::Context *context, GLbitfield barriers) override;
     gl::Error memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) override;
 
     gl::Error triggerDrawCallProgramRecompilation(const gl::Context *context, GLenum drawMode);
 
   private:
-    gl::Error prepareForDrawCall(const gl::Context *context, GLenum drawMode);
+    gl::Error prepareForDrawCall(const gl::Context *context,
+                                 const gl::DrawCallParams &drawCallParams);
 
     Renderer11 *mRenderer;
 };
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_D3D_D3D11_CONTEXT11_H_
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
@@ -48,52 +48,22 @@ gl::Error MarkAttachmentsDirty(const gl:
             ASSERT(texStorage11);
 
             texStorage11->markLevelDirty(attachment->mipLevel());
         }
     }
 
     return gl::NoError();
 }
-
-void UpdateCachedRenderTarget(const gl::Context *context,
-                              const gl::FramebufferAttachment *attachment,
-                              RenderTarget11 *&cachedRenderTarget,
-                              angle::ObserverBinding *channelBinding)
-{
-    RenderTarget11 *newRenderTarget = nullptr;
-    if (attachment)
-    {
-        // TODO(jmadill): Don't swallow this error.
-        gl::Error error = attachment->getRenderTarget(context, &newRenderTarget);
-        if (error.isError())
-        {
-            ERR() << "Internal rendertarget error: " << error;
-        }
-    }
-    if (newRenderTarget != cachedRenderTarget)
-    {
-        channelBinding->bind(newRenderTarget);
-        cachedRenderTarget = newRenderTarget;
-    }
-}
 }  // anonymous namespace
 
 Framebuffer11::Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer)
-    : FramebufferD3D(data, renderer),
-      mRenderer(renderer),
-      mCachedDepthStencilRenderTarget(nullptr),
-      mDepthStencilRenderTargetDirty(this, gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS)
+    : FramebufferD3D(data, renderer), mRenderer(renderer)
 {
     ASSERT(mRenderer != nullptr);
-    mCachedColorRenderTargets.fill(nullptr);
-    for (size_t colorIndex = 0; colorIndex < data.getColorAttachments().size(); ++colorIndex)
-    {
-        mColorRenderTargetsDirty.emplace_back(this, colorIndex);
-    }
 }
 
 Framebuffer11::~Framebuffer11()
 {
 }
 
 gl::Error Framebuffer11::markAttachmentsDirty(const gl::Context *context) const
 {
@@ -382,126 +352,50 @@ gl::Error Framebuffer11::blitImpl(const 
 }
 
 GLenum Framebuffer11::getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const
 {
     RenderTarget11 *renderTarget11 = GetAs<RenderTarget11>(renderTarget);
     return renderTarget11->getFormatSet().format().fboImplementationInternalFormat;
 }
 
-void Framebuffer11::updateColorRenderTarget(const gl::Context *context, size_t colorIndex)
-{
-    UpdateCachedRenderTarget(context, mState.getColorAttachment(colorIndex),
-                             mCachedColorRenderTargets[colorIndex],
-                             &mColorRenderTargetsDirty[colorIndex]);
-}
-
-void Framebuffer11::updateDepthStencilRenderTarget(const gl::Context *context)
-{
-    UpdateCachedRenderTarget(context, mState.getDepthOrStencilAttachment(),
-                             mCachedDepthStencilRenderTarget, &mDepthStencilRenderTargetDirty);
-}
-
-void Framebuffer11::syncState(const gl::Context *context,
-                              const gl::Framebuffer::DirtyBits &dirtyBits)
+gl::Error Framebuffer11::syncState(const gl::Context *context,
+                                   const gl::Framebuffer::DirtyBits &dirtyBits)
 {
-    const auto &mergedDirtyBits = dirtyBits | mInternalDirtyBits;
-    mInternalDirtyBits.reset();
-
-    for (auto dirtyBit : mergedDirtyBits)
-    {
-        switch (dirtyBit)
-        {
-            case gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT:
-            case gl::Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT:
-                updateDepthStencilRenderTarget(context);
-                break;
-            case gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS:
-            case gl::Framebuffer::DIRTY_BIT_READ_BUFFER:
-                break;
-            case gl::Framebuffer::DIRTY_BIT_DEFAULT_WIDTH:
-            case gl::Framebuffer::DIRTY_BIT_DEFAULT_HEIGHT:
-            case gl::Framebuffer::DIRTY_BIT_DEFAULT_SAMPLES:
-            case gl::Framebuffer::DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS:
-                break;
-            default:
-            {
-                ASSERT(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0 &&
-                       dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX);
-                size_t colorIndex =
-                    static_cast<size_t>(dirtyBit - gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0);
-                updateColorRenderTarget(context, colorIndex);
-                break;
-            }
-        }
-    }
-
-    // We should not have dirtied any additional state during our sync.
-    ASSERT(!mInternalDirtyBits.any());
-
-    FramebufferD3D::syncState(context, dirtyBits);
+    ANGLE_TRY(mRenderTargetCache.update(context, mState, dirtyBits));
+    ANGLE_TRY(FramebufferD3D::syncState(context, dirtyBits));
 
     // Call this last to allow the state manager to take advantage of the cached render targets.
     mRenderer->getStateManager()->invalidateRenderTarget();
 
     // Call this to syncViewport for framebuffer default parameters.
     if (mState.getDefaultWidth() != 0 || mState.getDefaultHeight() != 0)
     {
         mRenderer->getStateManager()->invalidateViewport(context);
     }
-}
 
-void Framebuffer11::onSubjectStateChange(const gl::Context *context,
-                                         angle::SubjectIndex index,
-                                         angle::SubjectMessage message)
-{
-    if (index == gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS)
-    {
-        // Stencil is redundant in this case.
-        mInternalDirtyBits.set(gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT);
-        mCachedDepthStencilRenderTarget = nullptr;
-    }
-    else
-    {
-        mInternalDirtyBits.set(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 + index);
-        mCachedColorRenderTargets[index] = nullptr;
-    }
-
-    // Notify the context we need to re-validate the RenderTarget.
-    // TODO(jmadill): Check that we're the active draw framebuffer.
-    mRenderer->getStateManager()->invalidateRenderTarget();
+    return gl::NoError();
 }
 
 gl::Error Framebuffer11::getSamplePosition(size_t index, GLfloat *xy) const
 {
     const gl::FramebufferAttachment *attachment = mState.getFirstNonNullAttachment();
     ASSERT(attachment);
     GLsizei sampleCount = attachment->getSamples();
 
     d3d11_gl::GetSamplePosition(sampleCount, index, xy);
     return gl::NoError();
 }
 
-bool Framebuffer11::hasAnyInternalDirtyBit() const
-{
-    return mInternalDirtyBits.any();
-}
-
-void Framebuffer11::syncInternalState(const gl::Context *context)
-{
-    syncState(context, gl::Framebuffer::DirtyBits());
-}
-
 RenderTarget11 *Framebuffer11::getFirstRenderTarget() const
 {
-    ASSERT(mInternalDirtyBits.none());
-    for (auto *renderTarget : mCachedColorRenderTargets)
+    for (auto *renderTarget : mRenderTargetCache.getColors())
     {
         if (renderTarget)
         {
             return renderTarget;
         }
     }
 
-    return mCachedDepthStencilRenderTarget;
+    return mRenderTargetCache.getDepthStencil();
 }
 
 }  // namespace rx
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
@@ -4,25 +4,26 @@
 // found in the LICENSE file.
 //
 
 // Framebuffer11.h: Defines the Framebuffer11 class.
 
 #ifndef LIBANGLE_RENDERER_D3D_D3D11_FRAMBUFFER11_H_
 #define LIBANGLE_RENDERER_D3D_D3D11_FRAMBUFFER11_H_
 
+#include "libANGLE/Observer.h"
+#include "libANGLE/renderer/RenderTargetCache.h"
 #include "libANGLE/renderer/d3d/FramebufferD3D.h"
 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
-#include "libANGLE/signal_utils.h"
 
 namespace rx
 {
 class Renderer11;
 
-class Framebuffer11 : public FramebufferD3D, public angle::ObserverInterface
+class Framebuffer11 : public FramebufferD3D
 {
   public:
     Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer);
     ~Framebuffer11() override;
 
     gl::Error discard(const gl::Context *context, size_t count, const GLenum *attachments) override;
     gl::Error invalidate(const gl::Context *context,
                          size_t count,
@@ -30,38 +31,30 @@ class Framebuffer11 : public Framebuffer
     gl::Error invalidateSub(const gl::Context *context,
                             size_t count,
                             const GLenum *attachments,
                             const gl::Rectangle &area) override;
 
     // Invalidate the cached swizzles of all bound texture attachments.
     gl::Error markAttachmentsDirty(const gl::Context *context) const;
 
-    void syncState(const gl::Context *context,
-                   const gl::Framebuffer::DirtyBits &dirtyBits) override;
+    gl::Error syncState(const gl::Context *context,
+                        const gl::Framebuffer::DirtyBits &dirtyBits) override;
 
-    const RenderTargetArray &getCachedColorRenderTargets() const
+    const gl::AttachmentArray<RenderTarget11 *> &getCachedColorRenderTargets() const
     {
-        return mCachedColorRenderTargets;
+        return mRenderTargetCache.getColors();
     }
     const RenderTarget11 *getCachedDepthStencilRenderTarget() const
     {
-        return mCachedDepthStencilRenderTarget;
+        return mRenderTargetCache.getDepthStencil();
     }
 
     RenderTarget11 *getFirstRenderTarget() const;
 
-    bool hasAnyInternalDirtyBit() const;
-    void syncInternalState(const gl::Context *context);
-
-    // Observer implementation.
-    void onSubjectStateChange(const gl::Context *context,
-                              angle::SubjectIndex index,
-                              angle::SubjectMessage message) override;
-
     gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
 
   private:
     gl::Error clearImpl(const gl::Context *context, const ClearParameters &clearParams) override;
 
     gl::Error readPixelsImpl(const gl::Context *context,
                              const gl::Rectangle &area,
                              GLenum format,
@@ -84,24 +77,15 @@ class Framebuffer11 : public Framebuffer
                              size_t count,
                              const GLenum *attachments,
                              bool useEXTBehavior) const;
     gl::Error invalidateAttachment(const gl::Context *context,
                                    const gl::FramebufferAttachment *attachment) const;
 
     GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override;
 
-    void updateColorRenderTarget(const gl::Context *context, size_t colorIndex);
-    void updateDepthStencilRenderTarget(const gl::Context *context);
-
     Renderer11 *const mRenderer;
-    RenderTargetArray mCachedColorRenderTargets;
-    RenderTarget11 *mCachedDepthStencilRenderTarget;
-
-    std::vector<angle::ObserverBinding> mColorRenderTargetsDirty;
-    angle::ObserverBinding mDepthStencilRenderTargetDirty;
-
-    gl::Framebuffer::DirtyBits mInternalDirtyBits;
+    RenderTargetCache<RenderTarget11> mRenderTargetCache;
 };
 
-}
+}  // namespace rx
 
 #endif // LIBANGLE_RENDERER_D3D_D3D11_FRAMBUFFER11_H_
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
@@ -223,34 +223,34 @@ void Image11::disassociateStorage()
         mAssociatedStorage->disassociateImage(mAssociatedImageIndex, this);
 
         mRecoverFromStorage   = false;
         mAssociatedStorage    = nullptr;
         mAssociatedImageIndex = gl::ImageIndex::MakeInvalid();
     }
 }
 
-bool Image11::redefine(GLenum target,
+bool Image11::redefine(gl::TextureType type,
                        GLenum internalformat,
                        const gl::Extents &size,
                        bool forceRelease)
 {
     if (mWidth != size.width || mHeight != size.height || mInternalFormat != internalformat ||
         forceRelease)
     {
         // End the association with the TextureStorage, since that data will be out of date.
         // Also reset mRecoveredFromStorageCount since this Image is getting completely redefined.
         disassociateStorage();
         mRecoveredFromStorageCount = 0;
 
         mWidth          = size.width;
         mHeight         = size.height;
         mDepth          = size.depth;
         mInternalFormat = internalformat;
-        mTarget         = target;
+        mType           = type;
 
         // compute the d3d format that will be used
         const d3d11::Format &formatInfo =
             d3d11::Format::Get(internalformat, mRenderer->getRenderer11DeviceCaps());
         mDXGIFormat = formatInfo.texFormat;
         mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
 
         releaseStagingTexture();
@@ -276,27 +276,27 @@ DXGI_FORMAT Image11::getDXGIFormat() con
 // into the target pixel rectangle.
 gl::Error Image11::loadData(const gl::Context *context,
                             const gl::Box &area,
                             const gl::PixelUnpackState &unpack,
                             GLenum type,
                             const void *input,
                             bool applySkipImages)
 {
-    const gl::InternalFormat &packFormat = gl::GetPackFormatInfo(mInternalFormat, type);
+    const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat);
     GLuint inputRowPitch                 = 0;
     ANGLE_TRY_RESULT(
-        packFormat.computeRowPitch(area.width, unpack.alignment, unpack.rowLength),
+        formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength),
         inputRowPitch);
     GLuint inputDepthPitch = 0;
-    ANGLE_TRY_RESULT(packFormat.computeDepthPitch(area.height, unpack.imageHeight, inputRowPitch),
+    ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(area.height, unpack.imageHeight, inputRowPitch),
                      inputDepthPitch);
     GLuint inputSkipBytes = 0;
     ANGLE_TRY_RESULT(
-        packFormat.computeSkipBytes(inputRowPitch, inputDepthPitch, unpack, applySkipImages),
+        formatInfo.computeSkipBytes(type, inputRowPitch, inputDepthPitch, unpack, applySkipImages),
         inputSkipBytes);
 
     const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat);
     GLuint outputPixelSize                      = dxgiFormatInfo.pixelBytes;
 
     const d3d11::Format &d3dFormatInfo =
         d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps());
     LoadImageFunction loadFunction = d3dFormatInfo.getLoadFunctions()(type).loadFunction;
@@ -317,17 +317,17 @@ gl::Error Image11::loadData(const gl::Co
 }
 
 gl::Error Image11::loadCompressedData(const gl::Context *context,
                                       const gl::Box &area,
                                       const void *input)
 {
     const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat);
     GLsizei inputRowPitch                = 0;
-    ANGLE_TRY_RESULT(formatInfo.computeRowPitch(area.width, 1, 0), inputRowPitch);
+    ANGLE_TRY_RESULT(formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0), inputRowPitch);
     GLsizei inputDepthPitch = 0;
     ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(area.height, 0, inputRowPitch), inputDepthPitch);
 
     const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat);
     GLuint outputPixelSize                      = dxgiFormatInfo.pixelBytes;
     GLuint outputBlockWidth                     = dxgiFormatInfo.blockWidth;
     GLuint outputBlockHeight                    = dxgiFormatInfo.blockHeight;
 
@@ -535,86 +535,92 @@ gl::Error Image11::createStagingTexture(
 
     int lodOffset  = 1;
     GLsizei width  = mWidth;
     GLsizei height = mHeight;
 
     // adjust size if needed for compressed textures
     d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset);
 
-    if (mTarget == GL_TEXTURE_3D)
-    {
-        D3D11_TEXTURE3D_DESC desc;
-        desc.Width          = width;
-        desc.Height         = height;
-        desc.Depth          = mDepth;
-        desc.MipLevels      = lodOffset + 1;
-        desc.Format         = dxgiFormat;
-        desc.Usage          = D3D11_USAGE_STAGING;
-        desc.BindFlags      = 0;
-        desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
-        desc.MiscFlags      = 0;
-
-        if (formatInfo.dataInitializerFunction != nullptr)
-        {
-            std::vector<D3D11_SUBRESOURCE_DATA> initialData;
-            std::vector<std::vector<BYTE>> textureData;
-            d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getRenderer11DeviceCaps(),
-                                              width, height, mDepth, lodOffset + 1, &initialData,
-                                              &textureData);
-
-            ANGLE_TRY(
-                mRenderer->allocateTexture(desc, formatInfo, initialData.data(), &mStagingTexture));
-        }
-        else
-        {
-            ANGLE_TRY(mRenderer->allocateTexture(desc, formatInfo, &mStagingTexture));
-        }
-
-        mStagingTexture.setDebugName("Image11::StagingTexture3D");
-        mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
-    }
-    else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY ||
-             mTarget == GL_TEXTURE_CUBE_MAP)
+    switch (mType)
     {
-        D3D11_TEXTURE2D_DESC desc;
-        desc.Width              = width;
-        desc.Height             = height;
-        desc.MipLevels          = lodOffset + 1;
-        desc.ArraySize          = 1;
-        desc.Format             = dxgiFormat;
-        desc.SampleDesc.Count   = 1;
-        desc.SampleDesc.Quality = 0;
-        desc.Usage              = D3D11_USAGE_STAGING;
-        desc.BindFlags          = 0;
-        desc.CPUAccessFlags     = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
-        desc.MiscFlags          = 0;
-
-        if (formatInfo.dataInitializerFunction != nullptr)
+        case gl::TextureType::_3D:
         {
-            std::vector<D3D11_SUBRESOURCE_DATA> initialData;
-            std::vector<std::vector<BYTE>> textureData;
-            d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getRenderer11DeviceCaps(),
-                                              width, height, 1, lodOffset + 1, &initialData,
-                                              &textureData);
+            D3D11_TEXTURE3D_DESC desc;
+            desc.Width          = width;
+            desc.Height         = height;
+            desc.Depth          = mDepth;
+            desc.MipLevels      = lodOffset + 1;
+            desc.Format         = dxgiFormat;
+            desc.Usage          = D3D11_USAGE_STAGING;
+            desc.BindFlags      = 0;
+            desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
+            desc.MiscFlags      = 0;
 
-            ANGLE_TRY(
-                mRenderer->allocateTexture(desc, formatInfo, initialData.data(), &mStagingTexture));
+            if (formatInfo.dataInitializerFunction != nullptr)
+            {
+                std::vector<D3D11_SUBRESOURCE_DATA> initialData;
+                std::vector<std::vector<BYTE>> textureData;
+                d3d11::GenerateInitialTextureData(
+                    mInternalFormat, mRenderer->getRenderer11DeviceCaps(), width, height, mDepth,
+                    lodOffset + 1, &initialData, &textureData);
+
+                ANGLE_TRY(mRenderer->allocateTexture(desc, formatInfo, initialData.data(),
+                                                     &mStagingTexture));
+            }
+            else
+            {
+                ANGLE_TRY(mRenderer->allocateTexture(desc, formatInfo, &mStagingTexture));
+            }
+
+            mStagingTexture.setDebugName("Image11::StagingTexture3D");
+            mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
         }
-        else
+        break;
+
+        case gl::TextureType::_2D:
+        case gl::TextureType::_2DArray:
+        case gl::TextureType::CubeMap:
         {
-            ANGLE_TRY(mRenderer->allocateTexture(desc, formatInfo, &mStagingTexture));
-        }
+            D3D11_TEXTURE2D_DESC desc;
+            desc.Width              = width;
+            desc.Height             = height;
+            desc.MipLevels          = lodOffset + 1;
+            desc.ArraySize          = 1;
+            desc.Format             = dxgiFormat;
+            desc.SampleDesc.Count   = 1;
+            desc.SampleDesc.Quality = 0;
+            desc.Usage              = D3D11_USAGE_STAGING;
+            desc.BindFlags          = 0;
+            desc.CPUAccessFlags     = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
+            desc.MiscFlags          = 0;
 
-        mStagingTexture.setDebugName("Image11::StagingTexture2D");
-        mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
-    }
-    else
-    {
-        UNREACHABLE();
+            if (formatInfo.dataInitializerFunction != nullptr)
+            {
+                std::vector<D3D11_SUBRESOURCE_DATA> initialData;
+                std::vector<std::vector<BYTE>> textureData;
+                d3d11::GenerateInitialTextureData(
+                    mInternalFormat, mRenderer->getRenderer11DeviceCaps(), width, height, 1,
+                    lodOffset + 1, &initialData, &textureData);
+
+                ANGLE_TRY(mRenderer->allocateTexture(desc, formatInfo, initialData.data(),
+                                                     &mStagingTexture));
+            }
+            else
+            {
+                ANGLE_TRY(mRenderer->allocateTexture(desc, formatInfo, &mStagingTexture));
+            }
+
+            mStagingTexture.setDebugName("Image11::StagingTexture2D");
+            mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
+        }
+        break;
+
+        default:
+            UNREACHABLE();
     }
 
     mDirty = false;
     return gl::NoError();
 }
 
 gl::Error Image11::map(const gl::Context *context, D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map)
 {
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.h
@@ -49,17 +49,20 @@ class Image11 : public ImageD3D
 
     bool isDirty() const override;
 
     gl::Error copyToStorage(const gl::Context *context,
                             TextureStorage *storage,
                             const gl::ImageIndex &index,
                             const gl::Box &region) override;
 
-    bool redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease) override;
+    bool redefine(gl::TextureType type,
+                  GLenum internalformat,
+                  const gl::Extents &size,
+                  bool forceRelease) override;
 
     DXGI_FORMAT getDXGIFormat() const;
 
     gl::Error loadData(const gl::Context *context,
                        const gl::Box &area,
                        const gl::PixelUnpackState &unpack,
                        GLenum type,
                        const void *input,
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
@@ -13,35 +13,28 @@
 #include "common/utilities.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/Program.h"
 #include "libANGLE/VertexArray.h"
 #include "libANGLE/VertexAttribute.h"
 #include "libANGLE/renderer/d3d/IndexDataManager.h"
 #include "libANGLE/renderer/d3d/ProgramD3D.h"
 #include "libANGLE/renderer/d3d/VertexDataManager.h"
-#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
 #include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
 #include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
-#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h"
 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
 
 namespace rx
 {
 
 namespace
 {
 
-size_t GetReservedBufferCount(bool usesPointSpriteEmulation)
-{
-    return usesPointSpriteEmulation ? 1 : 0;
-}
-
 GLenum GetGLSLAttributeType(const std::vector<sh::Attribute> &shaderAttributes, size_t index)
 {
     // Count matrices differently
     for (const sh::Attribute &attrib : shaderAttributes)
     {
         if (attrib.location == -1)
         {
             continue;
@@ -101,241 +94,58 @@ void PackedAttributeLayout::addAttribute
 }
 
 bool PackedAttributeLayout::operator==(const PackedAttributeLayout &other) const
 {
     return (numAttributes == other.numAttributes) && (flags == other.flags) &&
            (attributeData == other.attributeData);
 }
 
-InputLayoutCache::InputLayoutCache()
-    : mLayoutCache(kDefaultCacheSize * 2), mPointSpriteVertexBuffer(), mPointSpriteIndexBuffer()
+InputLayoutCache::InputLayoutCache() : mLayoutCache(kDefaultCacheSize * 2)
 {
 }
 
 InputLayoutCache::~InputLayoutCache()
 {
 }
 
 void InputLayoutCache::clear()
 {
     mLayoutCache.Clear();
-    mPointSpriteVertexBuffer.reset();
-    mPointSpriteIndexBuffer.reset();
 }
 
-gl::Error InputLayoutCache::applyVertexBuffers(
-    const gl::Context *context,
-    const std::vector<const TranslatedAttribute *> &currentAttributes,
-    GLenum mode,
-    GLint start,
-    bool isIndexedRendering)
-{
-    Renderer11 *renderer   = GetImplAs<Context11>(context)->getRenderer();
-    const gl::State &state = context->getGLState();
-    auto *stateManager     = renderer->getStateManager();
-    gl::Program *program   = state.getProgram();
-    ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
-
-    bool programUsesInstancedPointSprites = programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation();
-    bool instancedPointSpritesActive = programUsesInstancedPointSprites && (mode == GL_POINTS);
-
-    // Note that if we use instance emulation, we reserve the first buffer slot.
-    size_t reservedBuffers = GetReservedBufferCount(programUsesInstancedPointSprites);
-
-    for (size_t attribIndex = 0; attribIndex < (gl::MAX_VERTEX_ATTRIBS - reservedBuffers);
-         ++attribIndex)
-    {
-        ID3D11Buffer *buffer = nullptr;
-        UINT vertexStride    = 0;
-        UINT vertexOffset    = 0;
-
-        if (attribIndex < currentAttributes.size())
-        {
-            const auto &attrib      = *currentAttributes[attribIndex];
-            Buffer11 *bufferStorage = attrib.storage ? GetAs<Buffer11>(attrib.storage) : nullptr;
-
-            // If indexed pointsprite emulation is active, then we need to take a less efficent code path.
-            // Emulated indexed pointsprite rendering requires that the vertex buffers match exactly to
-            // the indices passed by the caller.  This could expand or shrink the vertex buffer depending
-            // on the number of points indicated by the index list or how many duplicates are found on the index list.
-            if (bufferStorage == nullptr)
-            {
-                ASSERT(attrib.vertexBuffer.get());
-                buffer = GetAs<VertexBuffer11>(attrib.vertexBuffer.get())->getBuffer().get();
-            }
-            else if (instancedPointSpritesActive && isIndexedRendering)
-            {
-                VertexArray11 *vao11 = GetImplAs<VertexArray11>(state.getVertexArray());
-                ASSERT(vao11->isCachedIndexInfoValid());
-                TranslatedIndexData *indexInfo = vao11->getCachedIndexInfo();
-                if (indexInfo->srcIndexData.srcBuffer != nullptr)
-                {
-                    const uint8_t *bufferData = nullptr;
-                    ANGLE_TRY(indexInfo->srcIndexData.srcBuffer->getData(context, &bufferData));
-                    ASSERT(bufferData != nullptr);
-
-                    ptrdiff_t offset =
-                        reinterpret_cast<ptrdiff_t>(indexInfo->srcIndexData.srcIndices);
-                    indexInfo->srcIndexData.srcBuffer  = nullptr;
-                    indexInfo->srcIndexData.srcIndices = bufferData + offset;
-                }
-
-                ANGLE_TRY_RESULT(bufferStorage->getEmulatedIndexedBuffer(
-                                     context, &indexInfo->srcIndexData, attrib, start),
-                                 buffer);
-            }
-            else
-            {
-                ANGLE_TRY_RESULT(
-                    bufferStorage->getBuffer(context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK),
-                    buffer);
-            }
-
-            vertexStride = attrib.stride;
-            ANGLE_TRY_RESULT(attrib.computeOffset(start), vertexOffset);
-        }
-
-        size_t bufferIndex = reservedBuffers + attribIndex;
-
-        stateManager->queueVertexBufferChange(bufferIndex, buffer, vertexStride, vertexOffset);
-    }
-
-    // Instanced PointSprite emulation requires two additional ID3D11Buffers. A vertex buffer needs
-    // to be created and added to the list of current buffers, strides and offsets collections.
-    // This buffer contains the vertices for a single PointSprite quad.
-    // An index buffer also needs to be created and applied because rendering instanced data on
-    // D3D11 FL9_3 requires DrawIndexedInstanced() to be used. Shaders that contain gl_PointSize and
-    // used without the GL_POINTS rendering mode require a vertex buffer because some drivers cannot
-    // handle missing vertex data and will TDR the system.
-    if (programUsesInstancedPointSprites)
-    {
-        const UINT pointSpriteVertexStride = sizeof(float) * 5;
-
-        if (!mPointSpriteVertexBuffer.valid())
-        {
-            static const float pointSpriteVertices[] =
-            {
-                // Position        // TexCoord
-               -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
-               -1.0f,  1.0f, 0.0f, 0.0f, 0.0f,
-                1.0f,  1.0f, 0.0f, 1.0f, 0.0f,
-                1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
-               -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
-                1.0f,  1.0f, 0.0f, 1.0f, 0.0f,
-            };
-
-            D3D11_SUBRESOURCE_DATA vertexBufferData = { pointSpriteVertices, 0, 0 };
-            D3D11_BUFFER_DESC vertexBufferDesc;
-            vertexBufferDesc.ByteWidth = sizeof(pointSpriteVertices);
-            vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
-            vertexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
-            vertexBufferDesc.CPUAccessFlags = 0;
-            vertexBufferDesc.MiscFlags = 0;
-            vertexBufferDesc.StructureByteStride = 0;
-
-            ANGLE_TRY(renderer->allocateResource(vertexBufferDesc, &vertexBufferData,
-                                                 &mPointSpriteVertexBuffer));
-        }
-
-        // Set the stride to 0 if GL_POINTS mode is not being used to instruct the driver to avoid
-        // indexing into the vertex buffer.
-        UINT stride = instancedPointSpritesActive ? pointSpriteVertexStride : 0;
-        stateManager->queueVertexBufferChange(0, mPointSpriteVertexBuffer.get(), stride, 0);
-
-        if (!mPointSpriteIndexBuffer.valid())
-        {
-            // Create an index buffer and set it for pointsprite rendering
-            static const unsigned short pointSpriteIndices[] =
-            {
-                0, 1, 2, 3, 4, 5,
-            };
-
-            D3D11_SUBRESOURCE_DATA indexBufferData = { pointSpriteIndices, 0, 0 };
-            D3D11_BUFFER_DESC indexBufferDesc;
-            indexBufferDesc.ByteWidth = sizeof(pointSpriteIndices);
-            indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
-            indexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
-            indexBufferDesc.CPUAccessFlags = 0;
-            indexBufferDesc.MiscFlags = 0;
-            indexBufferDesc.StructureByteStride = 0;
-
-            ANGLE_TRY(renderer->allocateResource(indexBufferDesc, &indexBufferData,
-                                                 &mPointSpriteIndexBuffer));
-        }
-
-        if (instancedPointSpritesActive)
-        {
-            // The index buffer is applied here because Instanced PointSprite emulation uses the a
-            // non-indexed rendering path in ANGLE (DrawArrays). This means that applyIndexBuffer()
-            // on the renderer will not be called and setting this buffer here ensures that the
-            // rendering path will contain the correct index buffers.
-            stateManager->setIndexBuffer(mPointSpriteIndexBuffer.get(), DXGI_FORMAT_R16_UINT, 0);
-        }
-    }
-
-    stateManager->applyVertexBufferChanges();
-    return gl::NoError();
-}
-
-gl::Error InputLayoutCache::updateVertexOffsetsForPointSpritesEmulation(
-    Renderer11 *renderer,
-    const std::vector<const TranslatedAttribute *> &currentAttributes,
-    GLint startVertex,
-    GLsizei emulatedInstanceId)
-{
-    auto *stateManager = renderer->getStateManager();
-
-    size_t reservedBuffers = GetReservedBufferCount(true);
-    for (size_t attribIndex = 0; attribIndex < currentAttributes.size(); ++attribIndex)
-    {
-        const auto &attrib = *currentAttributes[attribIndex];
-        size_t bufferIndex = reservedBuffers + attribIndex;
-
-        if (attrib.divisor > 0)
-        {
-            unsigned int offset = 0;
-            ANGLE_TRY_RESULT(attrib.computeOffset(startVertex), offset);
-            offset += (attrib.stride * (emulatedInstanceId / attrib.divisor));
-            stateManager->queueVertexOffsetChange(bufferIndex, offset);
-        }
-    }
-
-    stateManager->applyVertexBufferChanges();
-    return gl::NoError();
-}
-
-gl::Error InputLayoutCache::updateInputLayout(
+gl::Error InputLayoutCache::getInputLayout(
     Renderer11 *renderer,
     const gl::State &state,
     const std::vector<const TranslatedAttribute *> &currentAttributes,
-    GLenum mode,
     const AttribIndexArray &sortedSemanticIndices,
-    const DrawCallVertexParams &vertexParams)
+    const gl::DrawCallParams &drawCallParams,
+    const d3d11::InputLayout **inputLayoutOut)
 {
     gl::Program *program         = state.getProgram();
     const auto &shaderAttributes = program->getAttributes();
     PackedAttributeLayout layout;
 
     ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
     bool programUsesInstancedPointSprites =
         programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation();
-    bool instancedPointSpritesActive = programUsesInstancedPointSprites && (mode == GL_POINTS);
+    bool instancedPointSpritesActive =
+        programUsesInstancedPointSprites && (drawCallParams.mode() == GL_POINTS);
 
     if (programUsesInstancedPointSprites)
     {
         layout.flags |= PackedAttributeLayout::FLAG_USES_INSTANCED_SPRITES;
     }
 
     if (instancedPointSpritesActive)
     {
         layout.flags |= PackedAttributeLayout::FLAG_INSTANCED_SPRITES_ACTIVE;
     }
 
-    if (vertexParams.instances() > 0)
+    if (drawCallParams.instances() > 0)
     {
         layout.flags |= PackedAttributeLayout::FLAG_INSTANCED_RENDERING_ACTIVE;
     }
 
     const auto &attribs            = state.getVertexArray()->getVertexAttributes();
     const auto &bindings           = state.getVertexArray()->getVertexBindings();
     const auto &locationToSemantic = programD3D->getAttribLocationToD3DSemantics();
     int divisorMultiplier          = program->usesMultiview() ? program->getNumViews() : 1;
@@ -353,48 +163,45 @@ gl::Error InputLayoutCache::updateInputL
         const auto &currentValue =
             state.getVertexAttribCurrentValue(static_cast<unsigned int>(attribIndex));
         gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, currentValue.Type);
 
         layout.addAttributeData(glslElementType, d3dSemantic, vertexFormatType,
                                 binding.getDivisor() * divisorMultiplier);
     }
 
-    const d3d11::InputLayout *inputLayout = nullptr;
     if (layout.numAttributes > 0 || layout.flags != 0)
     {
         auto it = mLayoutCache.Get(layout);
         if (it != mLayoutCache.end())
         {
-            inputLayout = &it->second;
+            *inputLayoutOut = &it->second;
         }
         else
         {
             angle::TrimCache(mLayoutCache.max_size() / 2, kGCLimit, "input layout", &mLayoutCache);
 
             d3d11::InputLayout newInputLayout;
-            ANGLE_TRY(createInputLayout(renderer, sortedSemanticIndices, currentAttributes, mode,
-                                        program, vertexParams, &newInputLayout));
+            ANGLE_TRY(createInputLayout(renderer, sortedSemanticIndices, currentAttributes, program,
+                                        drawCallParams, &newInputLayout));
 
             auto insertIt = mLayoutCache.Put(layout, std::move(newInputLayout));
-            inputLayout   = &insertIt->second;
+            *inputLayoutOut = &insertIt->second;
         }
     }
 
-    renderer->getStateManager()->setInputLayout(inputLayout);
     return gl::NoError();
 }
 
 gl::Error InputLayoutCache::createInputLayout(
     Renderer11 *renderer,
     const AttribIndexArray &sortedSemanticIndices,
     const std::vector<const TranslatedAttribute *> &currentAttributes,
-    GLenum mode,
     gl::Program *program,
-    const DrawCallVertexParams &vertexParams,
+    const gl::DrawCallParams &drawCallParams,
     d3d11::InputLayout *inputLayoutOut)
 {
     ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
     auto featureLevel      = renderer->getRenderer11DeviceCaps().featureLevel;
 
     bool programUsesInstancedPointSprites =
         programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation();
 
@@ -434,28 +241,29 @@ gl::Error InputLayoutCache::createInputL
     {
         // On 9_3, we must ensure that slot 0 contains non-instanced data.
         // If slot 0 currently contains instanced data then we swap it with a non-instanced element.
         // Note that instancing is only available on 9_3 via ANGLE_instanced_arrays, since 9_3
         // doesn't support OpenGL ES 3.0.
         // As per the spec for ANGLE_instanced_arrays, not all attributes can be instanced
         // simultaneously, so a non-instanced element must exist.
 
-        GLsizei numIndicesPerInstance = 0;
-        if (vertexParams.instances() > 0)
+        UINT numIndicesPerInstance = 0;
+        if (drawCallParams.instances() > 0)
         {
-            // This may trigger an evaluation of the index range.
-            numIndicesPerInstance = vertexParams.vertexCount();
+            // This requires that the index range is resolved.
+            // Note: Vertex indexes can be arbitrarily large.
+            numIndicesPerInstance = drawCallParams.getClampedVertexCount<UINT>();
         }
 
         for (size_t elementIndex = 0; elementIndex < inputElementCount; ++elementIndex)
         {
             // If rendering points and instanced pointsprite emulation is being used, the
             // inputClass is required to be configured as per instance data
-            if (mode == GL_POINTS)
+            if (drawCallParams.mode() == GL_POINTS)
             {
                 inputElements[elementIndex].InputSlotClass       = D3D11_INPUT_PER_INSTANCE_DATA;
                 inputElements[elementIndex].InstanceDataStepRate = 1;
                 if (numIndicesPerInstance > 0 && currentAttributes[elementIndex]->divisor > 0)
                 {
                     inputElements[elementIndex].InstanceDataStepRate = numIndicesPerInstance;
                 }
             }
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
@@ -22,17 +22,16 @@
 #include "libANGLE/Error.h"
 #include "libANGLE/SizedMRUCache.h"
 #include "libANGLE/formatutils.h"
 #include "libANGLE/renderer/d3d/RendererD3D.h"
 #include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h"
 
 namespace rx
 {
-class DrawCallVertexParams;
 struct PackedAttributeLayout
 {
     PackedAttributeLayout();
     PackedAttributeLayout(const PackedAttributeLayout &other);
 
     void addAttributeData(GLenum glType,
                           UINT semanticIndex,
                           gl::VertexFormatType vertexFormatType,
@@ -81,55 +80,39 @@ class Renderer11;
 class InputLayoutCache : angle::NonCopyable
 {
   public:
     InputLayoutCache();
     ~InputLayoutCache();
 
     void clear();
 
-    gl::Error applyVertexBuffers(const gl::Context *context,
-                                 const std::vector<const TranslatedAttribute *> &currentAttributes,
-                                 GLenum mode,
-                                 GLint start,
-                                 bool isIndexedRendering);
-
-    gl::Error updateVertexOffsetsForPointSpritesEmulation(
-        Renderer11 *renderer,
-        const std::vector<const TranslatedAttribute *> &currentAttributes,
-        GLint startVertex,
-        GLsizei emulatedInstanceId);
-
     // Useful for testing
     void setCacheSize(size_t newCacheSize);
 
-    gl::Error updateInputLayout(Renderer11 *renderer,
-                                const gl::State &state,
-                                const std::vector<const TranslatedAttribute *> &currentAttributes,
-                                GLenum mode,
-                                const AttribIndexArray &sortedSemanticIndices,
-                                const DrawCallVertexParams &vertexParams);
+    gl::Error getInputLayout(Renderer11 *renderer,
+                             const gl::State &state,
+                             const std::vector<const TranslatedAttribute *> &currentAttributes,
+                             const AttribIndexArray &sortedSemanticIndices,
+                             const gl::DrawCallParams &drawCallParams,
+                             const d3d11::InputLayout **inputLayoutOut);
 
   private:
     gl::Error createInputLayout(Renderer11 *renderer,
                                 const AttribIndexArray &sortedSemanticIndices,
                                 const std::vector<const TranslatedAttribute *> &currentAttributes,
-                                GLenum mode,
                                 gl::Program *program,
-                                const DrawCallVertexParams &vertexParams,
+                                const gl::DrawCallParams &drawCallParams,
                                 d3d11::InputLayout *inputLayoutOut);
 
     // Starting cache size.
     static constexpr size_t kDefaultCacheSize = 1024;
 
     // The cache tries to clean up this many states at once.
     static constexpr size_t kGCLimit = 128;
 
     using LayoutCache = angle::base::HashingMRUCache<PackedAttributeLayout, d3d11::InputLayout>;
     LayoutCache mLayoutCache;
-
-    d3d11::Buffer mPointSpriteVertexBuffer;
-    d3d11::Buffer mPointSpriteIndexBuffer;
 };
 
 }  // namespace rx
 
 #endif // LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
@@ -186,17 +186,17 @@ gl::Error PixelTransfer11::copyBufferToT
 
     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
 
     // Are we doing a 2D or 3D copy?
     const auto *geometryShader = ((destSize.depth > 1) ? &mBufferToTextureGS : nullptr);
     StateManager11 *stateManager = mRenderer->getStateManager();
 
     stateManager->setDrawShaders(&mBufferToTextureVS, geometryShader, pixelShader);
-    stateManager->setShaderResource(gl::SHADER_FRAGMENT, 0, bufferSRV);
+    stateManager->setShaderResource(gl::ShaderType::Fragment, 0, bufferSRV);
     stateManager->setInputLayout(nullptr);
     stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
 
     stateManager->setSingleVertexBuffer(nullptr, 0, 0);
     stateManager->setSimpleBlendState(nullptr);
     stateManager->setDepthStencilState(&mCopyDepthStencilState, 0xFFFFFFFF);
     stateManager->setRasterizerState(&mCopyRasterizerState);
 
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp
@@ -195,25 +195,16 @@ const d3d11::Format &GetSurfaceFormatSet
 }  // anonymous namespace
 
 RenderTarget11::RenderTarget11(const d3d11::Format &formatSet) : mFormatSet(formatSet)
 {
 }
 
 RenderTarget11::~RenderTarget11()
 {
-    ASSERT(!hasObservers());
-}
-
-void RenderTarget11::signalDirty(const gl::Context *context)
-{
-    onStateChange(context, angle::SubjectMessage::STATE_CHANGE);
-
-    // Clear the list. We can't do this in the receiver because it would mutate during iteration.
-    resetObservers();
 }
 
 TextureRenderTarget11::TextureRenderTarget11(d3d11::RenderTargetView &&rtv,
                                              const TextureHelper11 &resource,
                                              const d3d11::SharedSRV &srv,
                                              const d3d11::SharedSRV &blitSRV,
                                              GLenum internalFormat,
                                              const d3d11::Format &formatSet,
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h
@@ -15,32 +15,30 @@
 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
 
 namespace rx
 {
 class SwapChain11;
 class Renderer11;
 
-class RenderTarget11 : public RenderTargetD3D, public angle::Subject
+class RenderTarget11 : public RenderTargetD3D
 {
   public:
     RenderTarget11(const d3d11::Format &formatSet);
     ~RenderTarget11() override;
 
     virtual const TextureHelper11 &getTexture() const                  = 0;
     virtual const d3d11::RenderTargetView &getRenderTargetView() const = 0;
     virtual const d3d11::DepthStencilView &getDepthStencilView() const = 0;
     virtual const d3d11::SharedSRV &getShaderResourceView() const      = 0;
     virtual const d3d11::SharedSRV &getBlitShaderResourceView() const  = 0;
 
     virtual unsigned int getSubresourceIndex() const = 0;
 
-    void signalDirty(const gl::Context *context) override;
-
     const d3d11::Format &getFormatSet() const { return mFormatSet; }
 
   protected:
     const d3d11::Format &mFormatSet;
 };
 
 class TextureRenderTarget11 : public RenderTarget11
 {
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
@@ -347,39 +347,16 @@ void GetTriFanIndices(const void *indice
             CopyTriangleFanIndices<GLuint>(indices, &(*bufferOut)[0], numTris);
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
-bool DrawCallNeedsTranslation(const gl::Context *context, GLenum mode)
-{
-    const auto &glState     = context->getGLState();
-    const gl::VertexArray *vertexArray = glState.getVertexArray();
-    VertexArray11 *vertexArray11       = GetImplAs<VertexArray11>(vertexArray);
-    // Direct drawing doesn't support dynamic attribute storage since it needs the first and count
-    // to translate when applyVertexBuffer. GL_LINE_LOOP and GL_TRIANGLE_FAN are not supported
-    // either since we need to simulate them in D3D.
-    if (vertexArray11->hasActiveDynamicAttrib(context) || mode == GL_LINE_LOOP ||
-        mode == GL_TRIANGLE_FAN)
-    {
-        return true;
-    }
-
-    ProgramD3D *programD3D = GetImplAs<ProgramD3D>(glState.getProgram());
-    if (InstancedPointSpritesActive(programD3D, mode))
-    {
-        return true;
-    }
-
-    return false;
-}
-
 bool IsArrayRTV(ID3D11RenderTargetView *rtv)
 {
     D3D11_RENDER_TARGET_VIEW_DESC desc;
     rtv->GetDesc(&desc);
     if (desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1DARRAY &&
         desc.Texture1DArray.ArraySize > 1)
         return true;
     if (desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DARRAY &&
@@ -425,22 +402,16 @@ void PopulateFormatDeviceCaps(ID3D11Devi
         {
             break;
         }
 
         *outMaxSamples = sampleCount;
     }
 }
 
-bool CullsEverything(const gl::State &glState)
-{
-    return (glState.getRasterizerState().cullFace &&
-            glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack);
-}
-
 }  // anonymous namespace
 
 Renderer11DeviceCaps::Renderer11DeviceCaps() = default;
 
 Renderer11::Renderer11(egl::Display *display)
     : RendererD3D(display),
       mCreateDebugDevice(false),
       mStateCache(),
@@ -1422,268 +1393,186 @@ SwapChainD3D *Renderer11::createSwapChai
                            backBufferFormat, depthBufferFormat, orientation, samples);
 }
 
 void *Renderer11::getD3DDevice()
 {
     return reinterpret_cast<void *>(mDevice);
 }
 
-bool Renderer11::applyPrimitiveType(const gl::State &glState, GLenum mode, GLsizei count)
+gl::Error Renderer11::drawArrays(const gl::Context *context, const gl::DrawCallParams &params)
 {
-    D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
-
-    GLsizei minCount = 0;
-
-    switch (mode)
-    {
-        case GL_POINTS:
-        {
-            bool usesPointSize = GetImplAs<ProgramD3D>(glState.getProgram())->usesPointSize();
-
-            // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
-            // which affects varying interpolation. Since the value of gl_PointSize is
-            // undefined when not written, just skip drawing to avoid unexpected results.
-            if (!usesPointSize && !glState.isTransformFeedbackActiveUnpaused())
-            {
-                // Notify developers of risking undefined behavior.
-                WARN() << "Point rendering without writing to gl_PointSize.";
-                return false;
-            }
-
-            // If instanced pointsprites are enabled and the shader uses gl_PointSize, the topology
-            // must be D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST.
-            if (usesPointSize && getWorkarounds().useInstancedPointSpriteEmulation)
-            {
-                primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
-            }
-            else
-            {
-                primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
-            }
-            minCount = 1;
-            break;
-        }
-        case GL_LINES:
-            primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST;
-            minCount          = 2;
-            break;
-        case GL_LINE_LOOP:
-            primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
-            minCount          = 2;
-            break;
-        case GL_LINE_STRIP:
-            primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
-            minCount          = 2;
-            break;
-        case GL_TRIANGLES:
-            primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
-            minCount          = CullsEverything(glState) ? std::numeric_limits<GLsizei>::max() : 3;
-            break;
-        case GL_TRIANGLE_STRIP:
-            primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
-            minCount          = CullsEverything(glState) ? std::numeric_limits<GLsizei>::max() : 3;
-            break;
-        // emulate fans via rewriting index buffer
-        case GL_TRIANGLE_FAN:
-            primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
-            minCount          = CullsEverything(glState) ? std::numeric_limits<GLsizei>::max() : 3;
-            break;
-        default:
-            UNREACHABLE();
-            return false;
-    }
-
-    mStateManager.setPrimitiveTopology(primitiveTopology);
-
-    return count >= minCount;
-}
-
-gl::Error Renderer11::drawArrays(const gl::Context *context,
-                                 GLenum mode,
-                                 GLint startVertex,
-                                 GLsizei count,
-                                 GLsizei instances)
-{
-    const auto &glState = context->getGLState();
-
-    if (!applyPrimitiveType(glState, mode, count))
+    if (params.vertexCount() < static_cast<size_t>(mStateManager.getCurrentMinimumDrawCount()))
     {
         return gl::NoError();
     }
 
-    DrawCallVertexParams vertexParams(startVertex, count, instances);
-    ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, vertexParams, false));
-
+    const auto &glState = context->getGLState();
     if (glState.isTransformFeedbackActiveUnpaused())
     {
         ANGLE_TRY(markTransformFeedbackUsage(context));
     }
 
     gl::Program *program = glState.getProgram();
     ASSERT(program != nullptr);
-    GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(program, instances);
+    GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(program, params.instances());
     ProgramD3D *programD3D        = GetImplAs<ProgramD3D>(program);
 
-    if (programD3D->usesGeometryShader(mode) && glState.isTransformFeedbackActiveUnpaused())
+    // Note: vertex indexes can be arbitrarily large.
+    UINT clampedVertexCount = params.getClampedVertexCount<UINT>();
+
+    if (programD3D->usesGeometryShader(params.mode()) &&
+        glState.isTransformFeedbackActiveUnpaused())
     {
         // Since we use a geometry if-and-only-if we rewrite vertex streams, transform feedback
         // won't get the correct output. To work around this, draw with *only* the stream out
         // first (no pixel shader) to feed the stream out buffers and then draw again with the
         // geometry shader + pixel shader to rasterize the primitives.
         mStateManager.setPixelShader(nullptr);
 
         if (adjustedInstanceCount > 0)
         {
-            mDeviceContext->DrawInstanced(count, adjustedInstanceCount, 0, 0);
+            mDeviceContext->DrawInstanced(clampedVertexCount, adjustedInstanceCount, 0, 0);
         }
         else
         {
-            mDeviceContext->Draw(count, 0);
+            mDeviceContext->Draw(clampedVertexCount, 0);
         }
 
         rx::ShaderExecutableD3D *pixelExe = nullptr;
         ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(&pixelExe, nullptr));
 
         // Skip the draw call if rasterizer discard is enabled (or no fragment shader).
         if (!pixelExe || glState.getRasterizerState().rasterizerDiscard)
         {
             return gl::NoError();
         }
 
         mStateManager.setPixelShader(&GetAs<ShaderExecutable11>(pixelExe)->getPixelShader());
 
         // Retrieve the geometry shader.
         rx::ShaderExecutableD3D *geometryExe = nullptr;
-        ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(context, mode, &geometryExe,
-                                                                    nullptr));
+        ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(context, params.mode(),
+                                                                    &geometryExe, nullptr));
 
         mStateManager.setGeometryShader(
             &GetAs<ShaderExecutable11>(geometryExe)->getGeometryShader());
 
         if (adjustedInstanceCount > 0)
         {
-            mDeviceContext->DrawInstanced(count, adjustedInstanceCount, 0, 0);
+            mDeviceContext->DrawInstanced(clampedVertexCount, adjustedInstanceCount, 0, 0);
         }
         else
         {
-            mDeviceContext->Draw(count, 0);
+            mDeviceContext->Draw(clampedVertexCount, 0);
         }
         return gl::NoError();
     }
 
-    if (mode == GL_LINE_LOOP)
+    if (params.mode() == GL_LINE_LOOP)
     {
-        return drawLineLoop(context, count, GL_NONE, nullptr, 0, adjustedInstanceCount);
+        return drawLineLoop(context, clampedVertexCount, GL_NONE, nullptr, 0,
+                            adjustedInstanceCount);
     }
 
-    if (mode == GL_TRIANGLE_FAN)
+    if (params.mode() == GL_TRIANGLE_FAN)
     {
-        return drawTriangleFan(context, count, GL_NONE, nullptr, 0, adjustedInstanceCount);
+        return drawTriangleFan(context, clampedVertexCount, GL_NONE, nullptr, 0,
+                               adjustedInstanceCount);
     }
 
     bool useInstancedPointSpriteEmulation =
         programD3D->usesPointSize() && getWorkarounds().useInstancedPointSpriteEmulation;
 
-    if (mode != GL_POINTS || !useInstancedPointSpriteEmulation)
+    if (params.mode() != GL_POINTS || !useInstancedPointSpriteEmulation)
     {
         if (adjustedInstanceCount == 0)
         {
-            mDeviceContext->Draw(count, 0);
+            mDeviceContext->Draw(clampedVertexCount, 0);
         }
         else
         {
-            mDeviceContext->DrawInstanced(count, adjustedInstanceCount, 0, 0);
+            mDeviceContext->DrawInstanced(clampedVertexCount, adjustedInstanceCount, 0, 0);
         }
         return gl::NoError();
     }
 
     // This code should not be reachable by multi-view programs.
     ASSERT(program->usesMultiview() == false);
 
     // If the shader is writing to gl_PointSize, then pointsprites are being rendered.
     // Emulating instanced point sprites for FL9_3 requires the topology to be
     // D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced is called instead.
     if (adjustedInstanceCount == 0)
     {
-        mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0);
+        mDeviceContext->DrawIndexedInstanced(6, clampedVertexCount, 0, 0, 0);
         return gl::NoError();
     }
 
     // If pointsprite emulation is used with glDrawArraysInstanced then we need to take a less
     // efficent code path. Instanced rendering of emulated pointsprites requires a loop to draw each
     // batch of points. An offset into the instanced data buffer is calculated and applied on each
     // iteration to ensure all instances are rendered correctly. Each instance being rendered
     // requires the inputlayout cache to reapply buffers and offsets.
-    for (GLsizei i = 0; i < instances; i++)
+    for (GLsizei i = 0; i < params.instances(); i++)
     {
-        ANGLE_TRY(mStateManager.updateVertexOffsetsForPointSpritesEmulation(startVertex, i));
-        mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0);
+        ANGLE_TRY(
+            mStateManager.updateVertexOffsetsForPointSpritesEmulation(params.baseVertex(), i));
+        mDeviceContext->DrawIndexedInstanced(6, clampedVertexCount, 0, 0, 0);
     }
 
     // This required by updateVertexOffsets... above but is outside of the loop for speed.
     mStateManager.invalidateVertexBuffer();
     return gl::NoError();
 }
 
-gl::Error Renderer11::drawElements(const gl::Context *context,
-                                   GLenum mode,
-                                   GLsizei count,
-                                   GLenum type,
-                                   const void *indices,
-                                   GLsizei instances)
+gl::Error Renderer11::drawElements(const gl::Context *context, const gl::DrawCallParams &params)
 {
-    const auto &glState = context->getGLState();
-
-    if (!applyPrimitiveType(glState, mode, count))
+    if (params.indexCount() < mStateManager.getCurrentMinimumDrawCount())
     {
         return gl::NoError();
     }
 
     // Transform feedback is not allowed for DrawElements, this error should have been caught at the
     // API validation layer.
+    const auto &glState = context->getGLState();
     ASSERT(!glState.isTransformFeedbackActiveUnpaused());
 
-    const auto &lazyIndexRange = context->getParams<gl::HasIndexRange>();
-
-    bool usePrimitiveRestartWorkaround =
-        UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), type);
-    DrawCallVertexParams vertexParams(!usePrimitiveRestartWorkaround, lazyIndexRange, 0, instances);
-
-    ANGLE_TRY(mStateManager.applyIndexBuffer(context, indices, count, type, lazyIndexRange,
-                                             usePrimitiveRestartWorkaround));
-    ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, vertexParams, true));
-
-    int startVertex = static_cast<int>(vertexParams.firstVertex());
+    // If this draw call is coming from an indirect call, offset by the indirect call's base vertex.
+    // No base vertex parameter exists for a normal drawElements, so params.baseVertex will be zero.
+    int startVertex = static_cast<int>(params.firstVertex() - params.baseVertex());
     int baseVertex  = -startVertex;
 
     const gl::Program *program    = glState.getProgram();
-    GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(program, instances);
-
-    if (mode == GL_LINE_LOOP)
+    GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(program, params.instances());
+
+    if (params.mode() == GL_LINE_LOOP)
     {
-        return drawLineLoop(context, count, type, indices, baseVertex, adjustedInstanceCount);
+        return drawLineLoop(context, params.indexCount(), params.type(), params.indices(),
+                            baseVertex, adjustedInstanceCount);
     }
 
-    if (mode == GL_TRIANGLE_FAN)
+    if (params.mode() == GL_TRIANGLE_FAN)
     {
-        return drawTriangleFan(context, count, type, indices, baseVertex, adjustedInstanceCount);
+        return drawTriangleFan(context, params.indexCount(), params.type(), params.indices(),
+                               baseVertex, adjustedInstanceCount);
     }
 
     const ProgramD3D *programD3D = GetImplAs<ProgramD3D>(glState.getProgram());
 
-    if (mode != GL_POINTS || !programD3D->usesInstancedPointSpriteEmulation())
+    if (params.mode() != GL_POINTS || !programD3D->usesInstancedPointSpriteEmulation())
     {
         if (adjustedInstanceCount == 0)
         {
-            mDeviceContext->DrawIndexed(count, 0, baseVertex);
+            mDeviceContext->DrawIndexed(params.indexCount(), 0, baseVertex);
         }
         else
         {
-            mDeviceContext->DrawIndexedInstanced(count, adjustedInstanceCount, 0, baseVertex, 0);
+            mDeviceContext->DrawIndexedInstanced(params.indexCount(), adjustedInstanceCount, 0,
+                                                 baseVertex, 0);
         }
         return gl::NoError();
     }
 
     // This code should not be reachable by multi-view programs.
     ASSERT(program->usesMultiview() == false);
 
     // If the shader is writing to gl_PointSize, then pointsprites are being rendered.
@@ -1691,166 +1580,85 @@ gl::Error Renderer11::drawElements(const
     // D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced is called instead.
     //
     // The count parameter passed to drawElements represents the total number of instances to be
     // rendered. Each instance is referenced by the bound index buffer from the the caller.
     //
     // Indexed pointsprite emulation replicates data for duplicate entries found in the index
     // buffer. This is not an efficent rendering mechanism and is only used on downlevel renderers
     // that do not support geometry shaders.
-    if (instances == 0)
+    if (params.instances() == 0)
     {
-        mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0);
+        mDeviceContext->DrawIndexedInstanced(6, params.indexCount(), 0, 0, 0);
         return gl::NoError();
     }
 
     // If pointsprite emulation is used with glDrawElementsInstanced then we need to take a less
     // efficent code path. Instanced rendering of emulated pointsprites requires a loop to draw each
     // batch of points. An offset into the instanced data buffer is calculated and applied on each
     // iteration to ensure all instances are rendered correctly.
-    GLsizei elementsToRender = vertexParams.vertexCount();
+    UINT clampedVertexCount = params.getClampedVertexCount<UINT>();
 
     // Each instance being rendered requires the inputlayout cache to reapply buffers and offsets.
-    for (GLsizei i = 0; i < instances; i++)
+    for (GLsizei i = 0; i < params.instances(); i++)
     {
         ANGLE_TRY(mStateManager.updateVertexOffsetsForPointSpritesEmulation(startVertex, i));
-        mDeviceContext->DrawIndexedInstanced(6, elementsToRender, 0, 0, 0);
+        mDeviceContext->DrawIndexedInstanced(6, clampedVertexCount, 0, 0, 0);
     }
     mStateManager.invalidateVertexBuffer();
     return gl::NoError();
 }
 
 gl::Error Renderer11::drawArraysIndirect(const gl::Context *context,
-                                         GLenum mode,
-                                         const void *indirect)
+                                         const gl::DrawCallParams &params)
 {
-    const auto &glState = context->getGLState();
-    ASSERT(!glState.isTransformFeedbackActiveUnpaused());
-
-    if (!applyPrimitiveType(glState, mode, std::numeric_limits<int>::max() - 1))
+    if (std::numeric_limits<GLsizei>::max() == mStateManager.getCurrentMinimumDrawCount())
     {
         return gl::NoError();
     }
 
+    const gl::State &glState = context->getGLState();
+    ASSERT(!glState.isTransformFeedbackActiveUnpaused());
+
     gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect);
     ASSERT(drawIndirectBuffer);
     Buffer11 *storage = GetImplAs<Buffer11>(drawIndirectBuffer);
-    uintptr_t offset  = reinterpret_cast<uintptr_t>(indirect);
-
-    if (!DrawCallNeedsTranslation(context, mode))
-    {
-        DrawCallVertexParams vertexParams(0, 0, 0);
-        ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, vertexParams, false));
-        ID3D11Buffer *buffer = nullptr;
-        ANGLE_TRY_RESULT(storage->getBuffer(context, BUFFER_USAGE_INDIRECT), buffer);
-        mDeviceContext->DrawInstancedIndirect(buffer, static_cast<unsigned int>(offset));
-        return gl::NoError();
-    }
-
-    const uint8_t *bufferData = nullptr;
-    ANGLE_TRY(storage->getData(context, &bufferData));
-    ASSERT(bufferData);
-    const gl::DrawArraysIndirectCommand *args =
-        reinterpret_cast<const gl::DrawArraysIndirectCommand *>(bufferData + offset);
-    GLuint count     = args->count;
-    GLuint instances = args->instanceCount;
-    GLuint first     = args->first;
-
-    DrawCallVertexParams vertexParams(first, count, instances);
-    ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, vertexParams, false));
-
-    if (mode == GL_LINE_LOOP)
-    {
-        return drawLineLoop(context, count, GL_NONE, nullptr, 0, instances);
-    }
-    if (mode == GL_TRIANGLE_FAN)
-    {
-        return drawTriangleFan(context, count, GL_NONE, nullptr, 0, instances);
-    }
-
-    mDeviceContext->DrawInstanced(count, instances, 0, 0);
+
+    uintptr_t offset = reinterpret_cast<uintptr_t>(params.indirect());
+
+    ID3D11Buffer *buffer = nullptr;
+    ANGLE_TRY_RESULT(storage->getBuffer(context, BUFFER_USAGE_INDIRECT), buffer);
+    mDeviceContext->DrawInstancedIndirect(buffer, static_cast<unsigned int>(offset));
     return gl::NoError();
 }
 
 gl::Error Renderer11::drawElementsIndirect(const gl::Context *context,
-                                           GLenum mode,
-                                           GLenum type,
-                                           const void *indirect)
+                                           const gl::DrawCallParams &params)
 {
-    const auto &glState = context->getGLState();
-    ASSERT(!glState.isTransformFeedbackActiveUnpaused());
-
-    if (!applyPrimitiveType(glState, mode, std::numeric_limits<int>::max() - 1))
+    if (std::numeric_limits<GLsizei>::max() == mStateManager.getCurrentMinimumDrawCount())
     {
         return gl::NoError();
     }
 
+    const gl::State &glState = context->getGLState();
+    ASSERT(!glState.isTransformFeedbackActiveUnpaused());
+
     gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect);
     ASSERT(drawIndirectBuffer);
     Buffer11 *storage = GetImplAs<Buffer11>(drawIndirectBuffer);
-    uintptr_t offset  = reinterpret_cast<uintptr_t>(indirect);
-
-    // TODO(jmadill): Remove the if statement and compute indirect parameters lazily.
-    bool usePrimitiveRestartWorkaround =
-        UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), type);
-
-    if (!DrawCallNeedsTranslation(context, mode) && !IsStreamingIndexData(context, type))
-    {
-        ANGLE_TRY(mStateManager.applyIndexBuffer(context, nullptr, 0, type, gl::HasIndexRange(),
-                                                 usePrimitiveRestartWorkaround));
-        DrawCallVertexParams vertexParams(0, 0, 0);
-        ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, vertexParams, true));
-        ID3D11Buffer *buffer = nullptr;
-        ANGLE_TRY_RESULT(storage->getBuffer(context, BUFFER_USAGE_INDIRECT), buffer);
-        mDeviceContext->DrawIndexedInstancedIndirect(buffer, static_cast<unsigned int>(offset));
-        return gl::NoError();
-    }
-
-    const uint8_t *bufferData = nullptr;
-    ANGLE_TRY(storage->getData(context, &bufferData));
-    ASSERT(bufferData);
-
-    const gl::DrawElementsIndirectCommand *cmd =
-        reinterpret_cast<const gl::DrawElementsIndirectCommand *>(bufferData + offset);
-    GLsizei count     = cmd->count;
-    GLuint instances  = cmd->primCount;
-    GLuint firstIndex = cmd->firstIndex;
-    GLint baseVertex  = cmd->baseVertex;
-
-    // TODO(jmadill): Fix const cast.
-    const gl::Type &typeInfo = gl::GetTypeInfo(type);
-    const void *indices =
-        reinterpret_cast<const void *>(static_cast<uintptr_t>(firstIndex * typeInfo.bytes));
-    gl::HasIndexRange lazyIndexRange(const_cast<gl::Context *>(context), count, type, indices);
-
-    ANGLE_TRY(mStateManager.applyIndexBuffer(context, indices, count, type, lazyIndexRange,
-                                             usePrimitiveRestartWorkaround));
-
-    DrawCallVertexParams vertexParams(false, lazyIndexRange, baseVertex, instances);
-
-    ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, vertexParams, true));
-
-    int baseVertexLocation = -static_cast<int>(lazyIndexRange.getIndexRange().value().start);
-
-    if (mode == GL_LINE_LOOP)
-    {
-        return drawLineLoop(context, count, type, indices, baseVertexLocation, instances);
-    }
-
-    if (mode == GL_TRIANGLE_FAN)
-    {
-        return drawTriangleFan(context, count, type, indices, baseVertexLocation, instances);
-    }
-
-    mDeviceContext->DrawIndexedInstanced(count, instances, 0, baseVertexLocation, 0);
+    uintptr_t offset  = reinterpret_cast<uintptr_t>(params.indirect());
+
+    ID3D11Buffer *buffer = nullptr;
+    ANGLE_TRY_RESULT(storage->getBuffer(context, BUFFER_USAGE_INDIRECT), buffer);
+    mDeviceContext->DrawIndexedInstancedIndirect(buffer, static_cast<unsigned int>(offset));
     return gl::NoError();
 }
 
 gl::Error Renderer11::drawLineLoop(const gl::Context *context,
-                                   GLsizei count,
+                                   GLuint count,
                                    GLenum type,
                                    const void *indexPointer,
                                    int baseVertex,
                                    int instances)
 {
     const gl::State &glState       = context->getGLState();
     gl::VertexArray *vao           = glState.getVertexArray();
     gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
@@ -1877,18 +1685,16 @@ gl::Error Renderer11::drawLineLoop(const
         if (error.isError())
         {
             SafeDelete(mLineLoopIB);
             return error;
         }
     }
 
     // Checked by Renderer11::applyPrimitiveType
-    ASSERT(count >= 0);
-
     if (static_cast<unsigned int>(count) + 1 >
         (std::numeric_limits<unsigned int>::max() / sizeof(unsigned int)))
     {
         return gl::OutOfMemory() << "Failed to create a 32-bit looping index buffer for "
                                     "GL_LINE_LOOP, too many indices required.";
     }
 
     GetLineLoopIndices(indices, type, static_cast<GLuint>(count),
@@ -1924,17 +1730,17 @@ gl::Error Renderer11::drawLineLoop(const
     {
         mDeviceContext->DrawIndexed(indexCount, 0, baseVertex);
     }
 
     return gl::NoError();
 }
 
 gl::Error Renderer11::drawTriangleFan(const gl::Context *context,
-                                      GLsizei count,
+                                      GLuint count,
                                       GLenum type,
                                       const void *indices,
                                       int baseVertex,
                                       int instances)
 {
     const gl::State &glState       = context->getGLState();
     gl::VertexArray *vao           = glState.getVertexArray();
     gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
@@ -2459,17 +2265,17 @@ gl::Error Renderer11::copyImage2D(const 
 }
 
 gl::Error Renderer11::copyImageCube(const gl::Context *context,
                                     const gl::Framebuffer *framebuffer,
                                     const gl::Rectangle &sourceRect,
                                     GLenum destFormat,
                                     const gl::Offset &destOffset,
                                     TextureStorage *storage,
-                                    GLenum target,
+                                    gl::TextureTarget target,
                                     GLint level)
 {
     TextureStorage11_Cube *storage11 = GetAs<TextureStorage11_Cube>(storage);
     ASSERT(storage11);
 
     gl::ImageIndex index              = gl::ImageIndex::MakeCube(target, level);
     RenderTargetD3D *destRenderTarget = nullptr;
     ANGLE_TRY(storage11->getRenderTarget(context, index, &destRenderTarget));
@@ -2533,17 +2339,17 @@ gl::Error Renderer11::copyImage2DArray(c
 gl::Error Renderer11::copyTexture(const gl::Context *context,
                                   const gl::Texture *source,
                                   GLint sourceLevel,
                                   const gl::Rectangle &sourceRect,
                                   GLenum destFormat,
                                   GLenum destType,
                                   const gl::Offset &destOffset,
                                   TextureStorage *storage,
-                                  GLenum destTarget,
+                                  gl::TextureTarget destTarget,
                                   GLint destLevel,
                                   bool unpackFlipY,
                                   bool unpackPremultiplyAlpha,
                                   bool unpackUnmultiplyAlpha)
 {
     TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
 
     TextureStorage *sourceStorage = nullptr;
@@ -2552,17 +2358,17 @@ gl::Error Renderer11::copyTexture(const 
     TextureStorage11_2D *sourceStorage11 = GetAs<TextureStorage11_2D>(sourceStorage);
     ASSERT(sourceStorage11);
 
     TextureStorage11 *destStorage11 = GetAs<TextureStorage11>(storage);
     ASSERT(destStorage11);
 
     // Check for fast path where a CopySubresourceRegion can be used.
     if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha && !unpackFlipY &&
-        source->getFormat(GL_TEXTURE_2D, sourceLevel).info->format == destFormat &&
+        source->getFormat(gl::TextureTarget::_2D, sourceLevel).info->format == destFormat &&
         sourceStorage11->getFormatSet().internalFormat ==
             destStorage11->getFormatSet().internalFormat)
     {
         const TextureHelper11 *sourceResource = nullptr;
         ANGLE_TRY(sourceStorage11->getResource(context, &sourceResource));
 
         gl::ImageIndex sourceIndex = gl::ImageIndex::Make2D(sourceLevel);
         UINT sourceSubresource     = sourceStorage11->getSubresourceIndex(sourceIndex);
@@ -2596,31 +2402,33 @@ gl::Error Renderer11::copyTexture(const 
         ANGLE_TRY(destStorage11->getRenderTarget(context, destIndex, &destRenderTargetD3D));
 
         RenderTarget11 *destRenderTarget11 = GetAs<RenderTarget11>(destRenderTargetD3D);
 
         const d3d11::RenderTargetView &destRTV = destRenderTarget11->getRenderTargetView();
         ASSERT(destRTV.valid());
 
         gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
-        gl::Extents sourceSize(
-            static_cast<int>(source->getWidth(source->getTarget(), sourceLevel)),
-            static_cast<int>(source->getHeight(source->getTarget(), sourceLevel)), 1);
+        gl::Extents sourceSize(static_cast<int>(source->getWidth(
+                                   NonCubeTextureTypeToTarget(source->getType()), sourceLevel)),
+                               static_cast<int>(source->getHeight(
+                                   NonCubeTextureTypeToTarget(source->getType()), sourceLevel)),
+                               1);
         if (unpackFlipY)
         {
             sourceArea.y += sourceArea.height;
             sourceArea.height = -sourceArea.height;
         }
 
         gl::Box destArea(destOffset.x, destOffset.y, 0, sourceRect.width, sourceRect.height, 1);
         gl::Extents destSize(destRenderTarget11->getWidth(), destRenderTarget11->getHeight(), 1);
 
         // Use nearest filtering because source and destination are the same size for the direct
         // copy
-        GLenum sourceFormat = source->getFormat(GL_TEXTURE_2D, sourceLevel).info->format;
+        GLenum sourceFormat = source->getFormat(gl::TextureTarget::_2D, sourceLevel).info->format;
         ANGLE_TRY(mBlit->copyTexture(context, *sourceSRV, sourceArea, sourceSize, sourceFormat,
                                      destRTV, destArea, destSize, nullptr, destFormat, destType,
                                      GL_NEAREST, false, unpackPremultiplyAlpha,
                                      unpackUnmultiplyAlpha));
     }
 
     destStorage11->markLevelDirty(destLevel);
 
@@ -2708,41 +2516,44 @@ gl::Error Renderer11::createRenderTarget
                          (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) |
                          (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0);
 
         // The format must be either an RTV or a DSV
         ASSERT(bindRTV != bindDSV);
 
         TextureHelper11 texture;
         ANGLE_TRY(allocateTexture(desc, formatInfo, &texture));
+        texture.setDebugName("createRenderTarget.Texture");
 
         d3d11::SharedSRV srv;
         d3d11::SharedSRV blitSRV;
         if (bindSRV)
         {
             D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
             srvDesc.Format        = formatInfo.srvFormat;
             srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D
                                                             : D3D11_SRV_DIMENSION_TEXTURE2DMS;
             srvDesc.Texture2D.MostDetailedMip = 0;
             srvDesc.Texture2D.MipLevels       = 1;
 
             ANGLE_TRY(allocateResource(srvDesc, texture.get(), &srv));
+            srv.setDebugName("createRenderTarget.SRV");
 
             if (formatInfo.blitSRVFormat != formatInfo.srvFormat)
             {
                 D3D11_SHADER_RESOURCE_VIEW_DESC blitSRVDesc;
                 blitSRVDesc.Format        = formatInfo.blitSRVFormat;
                 blitSRVDesc.ViewDimension = (supportedSamples == 0)
                                                 ? D3D11_SRV_DIMENSION_TEXTURE2D
                                                 : D3D11_SRV_DIMENSION_TEXTURE2DMS;
                 blitSRVDesc.Texture2D.MostDetailedMip = 0;
                 blitSRVDesc.Texture2D.MipLevels       = 1;
 
                 ANGLE_TRY(allocateResource(blitSRVDesc, texture.get(), &blitSRV));
+                blitSRV.setDebugName("createRenderTarget.BlitSRV");
             }
             else
             {
                 blitSRV = srv.makeCopy();
             }
         }
 
         if (bindDSV)
@@ -2751,30 +2562,32 @@ gl::Error Renderer11::createRenderTarget
             dsvDesc.Format        = formatInfo.dsvFormat;
             dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D
                                                             : D3D11_DSV_DIMENSION_TEXTURE2DMS;
             dsvDesc.Texture2D.MipSlice = 0;
             dsvDesc.Flags              = 0;
 
             d3d11::DepthStencilView dsv;
             ANGLE_TRY(allocateResource(dsvDesc, texture.get(), &dsv));
+            dsv.setDebugName("createRenderTarget.DSV");
 
             *outRT = new TextureRenderTarget11(std::move(dsv), texture, srv, format, formatInfo,
                                                width, height, 1, supportedSamples);
         }
         else if (bindRTV)
         {
             D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
             rtvDesc.Format        = formatInfo.rtvFormat;
             rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D
                                                             : D3D11_RTV_DIMENSION_TEXTURE2DMS;
             rtvDesc.Texture2D.MipSlice = 0;
 
             d3d11::RenderTargetView rtv;
             ANGLE_TRY(allocateResource(rtvDesc, texture.get(), &rtv));
+            rtv.setDebugName("createRenderTarget.RTV");
 
             if (formatInfo.dataInitializerFunction != nullptr)
             {
                 const float clearValues[4] = {0.0f, 0.0f, 0.0f, 1.0f};
                 mDeviceContext->ClearRenderTargetView(rtv.get(), clearValues);
             }
 
             *outRT = new TextureRenderTarget11(std::move(rtv), texture, srv, blitSRV, format,
@@ -2820,17 +2633,17 @@ gl::Error Renderer11::loadExecutable(con
                                      const std::vector<D3DVarying> &streamOutVaryings,
                                      bool separatedOutputBuffers,
                                      ShaderExecutableD3D **outExecutable)
 {
     ShaderData shaderData(function, length);
 
     switch (type)
     {
-        case gl::SHADER_VERTEX:
+        case gl::ShaderType::Vertex:
         {
             d3d11::VertexShader vertexShader;
             d3d11::GeometryShader streamOutShader;
             ANGLE_TRY(allocateResource(shaderData, &vertexShader));
 
             if (!streamOutVaryings.empty())
             {
                 std::vector<D3D11_SO_DECLARATION_ENTRY> soDeclaration;
@@ -2851,31 +2664,31 @@ gl::Error Renderer11::loadExecutable(con
 
                 ANGLE_TRY(allocateResource(shaderData, &soDeclaration, &streamOutShader));
             }
 
             *outExecutable = new ShaderExecutable11(function, length, std::move(vertexShader),
                                                     std::move(streamOutShader));
         }
         break;
-        case gl::SHADER_FRAGMENT:
+        case gl::ShaderType::Fragment:
         {
             d3d11::PixelShader pixelShader;
             ANGLE_TRY(allocateResource(shaderData, &pixelShader));
             *outExecutable = new ShaderExecutable11(function, length, std::move(pixelShader));
         }
         break;
-        case gl::SHADER_GEOMETRY:
+        case gl::ShaderType::Geometry:
         {
             d3d11::GeometryShader geometryShader;
             ANGLE_TRY(allocateResource(shaderData, &geometryShader));
             *outExecutable = new ShaderExecutable11(function, length, std::move(geometryShader));
         }
         break;
-        case gl::SHADER_COMPUTE:
+        case gl::ShaderType::Compute:
         {
             d3d11::ComputeShader computeShader;
             ANGLE_TRY(allocateResource(shaderData, &computeShader));
             *outExecutable = new ShaderExecutable11(function, length, std::move(computeShader));
         }
         break;
         default:
             UNREACHABLE();
@@ -2892,26 +2705,26 @@ gl::Error Renderer11::compileToExecutabl
                                           bool separatedOutputBuffers,
                                           const angle::CompilerWorkaroundsD3D &workarounds,
                                           ShaderExecutableD3D **outExectuable)
 {
     std::stringstream profileStream;
 
     switch (type)
     {
-        case gl::SHADER_VERTEX:
+        case gl::ShaderType::Vertex:
             profileStream << "vs";
             break;
-        case gl::SHADER_FRAGMENT:
+        case gl::ShaderType::Fragment:
             profileStream << "ps";
             break;
-        case gl::SHADER_GEOMETRY:
+        case gl::ShaderType::Geometry:
             profileStream << "gs";
             break;
-        case gl::SHADER_COMPUTE:
+        case gl::ShaderType::Compute:
             profileStream << "cs";
             break;
         default:
             UNREACHABLE();
             return gl::InternalError();
     }
 
     profileStream << "_" << getMajorShaderModel() << "_" << getMinorShaderModel()
@@ -3239,16 +3052,17 @@ gl::Error Renderer11::readFromAttachment
     }
 
     gl::Extents safeSize(safeArea.width, safeArea.height, 1);
     TextureHelper11 stagingHelper;
     ANGLE_TRY_RESULT(
         createStagingTexture(textureHelper.getTextureType(), textureHelper.getFormatSet(), safeSize,
                              StagingAccess::READ),
         stagingHelper);
+    stagingHelper.setDebugName("readFromAttachment::stagingHelper");
 
     TextureHelper11 resolvedTextureHelper;
 
     // "srcTexture" usually points to the source texture.
     // For 2D multisampled textures, it points to the multisampled resolve texture.
     const TextureHelper11 *srcTexture = &textureHelper;
 
     if (textureHelper.is2D() && textureHelper.getSampleCount() > 1)
@@ -3263,16 +3077,17 @@ gl::Error Renderer11::readFromAttachment
         resolveDesc.SampleDesc.Quality = 0;
         resolveDesc.Usage              = D3D11_USAGE_DEFAULT;
         resolveDesc.BindFlags          = 0;
         resolveDesc.CPUAccessFlags     = 0;
         resolveDesc.MiscFlags          = 0;
 
         ANGLE_TRY(
             allocateTexture(resolveDesc, textureHelper.getFormatSet(), &resolvedTextureHelper));
+        resolvedTextureHelper.setDebugName("readFromAttachment::resolvedTextureHelper");
 
         mDeviceContext->ResolveSubresource(resolvedTextureHelper.get(), 0, textureHelper.get(),
                                            sourceSubResource, textureHelper.getFormat());
 
         sourceSubResource = 0;
         srcTexture        = &resolvedTextureHelper;
     }
 
@@ -3779,36 +3594,39 @@ GLenum Renderer11::getVertexComponentTyp
     const auto &format =
         d3d11::GetVertexFormatInfo(vertexFormatType, mRenderer11DeviceCaps.featureLevel);
     return d3d11::GetComponentType(format.nativeFormat);
 }
 
 gl::ErrorOrResult<unsigned int> Renderer11::getVertexSpaceRequired(
     const gl::VertexAttribute &attrib,
     const gl::VertexBinding &binding,
-    GLsizei count,
+    size_t count,
     GLsizei instances) const
 {
     if (!attrib.enabled)
     {
         return 16u;
     }
 
     unsigned int elementCount  = 0;
     const unsigned int divisor = binding.getDivisor();
     if (instances == 0 || divisor == 0)
     {
-        elementCount = count;
+        // This could be a clipped cast.
+        elementCount = gl::clampCast<unsigned int>(count);
     }
     else
     {
         // Round up to divisor, if possible
         elementCount = UnsignedCeilDivide(static_cast<unsigned int>(instances), divisor);
     }
 
+    ASSERT(elementCount > 0);
+
     gl::VertexFormatType formatType      = gl::GetVertexFormatType(attrib);
     const D3D_FEATURE_LEVEL featureLevel = mRenderer11DeviceCaps.featureLevel;
     const d3d11::VertexFormat &vertexFormatInfo =
         d3d11::GetVertexFormatInfo(formatType, featureLevel);
     const d3d11::DXGIFormatSize &dxgiFormatInfo =
         d3d11::GetDXGIFormatSizeInfo(vertexFormatInfo.nativeFormat);
     unsigned int elementSize = dxgiFormatInfo.pixelBytes;
     if (elementSize > std::numeric_limits<unsigned int>::max() / elementCount)
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
@@ -143,18 +143,16 @@ class Renderer11 : public RendererD3D
                                  IUnknown *d3dTexture,
                                  EGLint *width,
                                  EGLint *height,
                                  const angle::Format **angleFormat) const override;
     egl::Error validateShareHandle(const egl::Config *config,
                                    HANDLE shareHandle,
                                    const egl::AttributeMap &attribs) const override;
 
-    bool applyPrimitiveType(const gl::State &glState, GLenum mode, GLsizei count);
-
     // lost device
     bool testDeviceLost() override;
     bool testDeviceResettable() override;
 
     std::string getRendererDescription() const;
     DeviceIdentifier getAdapterIdentifier() const override;
 
     unsigned int getReservedVertexUniformVectors() const;
@@ -177,17 +175,17 @@ class Renderer11 : public RendererD3D
                           TextureStorage *storage,
                           GLint level) override;
     gl::Error copyImageCube(const gl::Context *context,
                             const gl::Framebuffer *framebuffer,
                             const gl::Rectangle &sourceRect,
                             GLenum destFormat,
                             const gl::Offset &destOffset,
                             TextureStorage *storage,
-                            GLenum target,
+                            gl::TextureTarget target,
                             GLint level) override;
     gl::Error copyImage3D(const gl::Context *context,
                           const gl::Framebuffer *framebuffer,
                           const gl::Rectangle &sourceRect,
                           GLenum destFormat,
                           const gl::Offset &destOffset,
                           TextureStorage *storage,
                           GLint level) override;
@@ -202,17 +200,17 @@ class Renderer11 : public RendererD3D
     gl::Error copyTexture(const gl::Context *context,
                           const gl::Texture *source,
                           GLint sourceLevel,
                           const gl::Rectangle &sourceRect,
                           GLenum destFormat,
                           GLenum destType,
                           const gl::Offset &destOffset,
                           TextureStorage *storage,
-                          GLenum destTarget,
+                          gl::TextureTarget destTarget,
                           GLint destLevel,
                           bool unpackFlipY,
                           bool unpackPremultiplyAlpha,
                           bool unpackUnmultiplyAlpha) override;
     gl::Error copyCompressedTexture(const gl::Context *context,
                                     const gl::Texture *source,
                                     GLint sourceLevel,
                                     TextureStorage *storage,
@@ -340,17 +338,17 @@ class Renderer11 : public RendererD3D
     VertexConversionType getVertexConversionType(
         gl::VertexFormatType vertexFormatType) const override;
     GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const override;
 
     // Warning: you should ensure binding really matches attrib.bindingIndex before using this
     // function.
     gl::ErrorOrResult<unsigned int> getVertexSpaceRequired(const gl::VertexAttribute &attrib,
                                                            const gl::VertexBinding &binding,
-                                                           GLsizei count,
+                                                           size_t count,
                                                            GLsizei instances) const override;
 
     gl::Error readFromAttachment(const gl::Context *context,
                                  const gl::FramebufferAttachment &srcAttachment,
                                  const gl::Rectangle &sourceArea,
                                  GLenum format,
                                  GLenum type,
                                  GLuint outputPitch,
@@ -375,34 +373,20 @@ class Renderer11 : public RendererD3D
     StateManager11 *getStateManager() { return &mStateManager; }
 
     void onSwap();
     void onBufferCreate(const Buffer11 *created);
     void onBufferDelete(const Buffer11 *deleted);
 
     DeviceImpl *createEGLDevice() override;
 
-    gl::Error drawArrays(const gl::Context *context,
-                         GLenum mode,
-                         GLint startVertex,
-                         GLsizei count,
-                         GLsizei instances);
-
-    gl::Error drawElements(const gl::Context *context,
-                           GLenum mode,
-                           GLsizei count,
-                           GLenum type,
-                           const void *indices,
-                           GLsizei instances);
-
-    gl::Error drawArraysIndirect(const gl::Context *context, GLenum mode, const void *indirect);
-    gl::Error drawElementsIndirect(const gl::Context *context,
-                                   GLenum mode,
-                                   GLenum type,
-                                   const void *indirect);
+    gl::Error drawArrays(const gl::Context *context, const gl::DrawCallParams &params);
+    gl::Error drawElements(const gl::Context *context, const gl::DrawCallParams &params);
+    gl::Error drawArraysIndirect(const gl::Context *context, const gl::DrawCallParams &params);
+    gl::Error drawElementsIndirect(const gl::Context *context, const gl::DrawCallParams &params);
 
     // Necessary hack for default framebuffers in D3D.
     FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
 
     gl::Error getScratchMemoryBuffer(size_t requestedSize, angle::MemoryBuffer **bufferOut);
 
     gl::Version getMaxSupportedESVersion() const override;
 
@@ -472,23 +456,23 @@ class Renderer11 : public RendererD3D
     void generateCaps(gl::Caps *outCaps,
                       gl::TextureCapsMap *outTextureCaps,
                       gl::Extensions *outExtensions,
                       gl::Limitations *outLimitations) const override;
 
     angle::WorkaroundsD3D generateWorkarounds() const override;
 
     gl::Error drawLineLoop(const gl::Context *context,
-                           GLsizei count,
+                           GLuint count,
                            GLenum type,
                            const void *indices,
                            int baseVertex,
                            int instances);
     gl::Error drawTriangleFan(const gl::Context *context,
-                              GLsizei count,
+                              GLuint count,
                               GLenum type,
                               const void *indices,
                               int baseVertex,
                               int instances);
 
     gl::ErrorOrResult<TextureHelper11> resolveMultisampledTexture(const gl::Context *context,
                                                                   RenderTarget11 *renderTarget,
                                                                   bool depth,
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
@@ -4,94 +4,97 @@
 // found in the LICENSE file.
 //
 
 // StateManager11.cpp: Defines a class for caching D3D11 state
 
 #include "libANGLE/renderer/d3d/d3d11/StateManager11.h"
 
 #include "common/bitset_utils.h"
+#include "common/mathutil.h"
 #include "common/utilities.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/Query.h"
 #include "libANGLE/VertexArray.h"
 #include "libANGLE/renderer/d3d/TextureD3D.h"
 #include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
 #include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
 #include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h"
 #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
 #include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
 #include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
 #include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h"
 #include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
+#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h"
 
 namespace rx
 {
 
 namespace
 {
 bool ImageIndexConflictsWithSRV(const gl::ImageIndex &index, D3D11_SHADER_RESOURCE_VIEW_DESC desc)
 {
     unsigned mipLevel  = index.mipIndex;
-    GLenum textureType = index.type;
+    gl::TextureType textureType = index.type;
 
     switch (desc.ViewDimension)
     {
         case D3D11_SRV_DIMENSION_TEXTURE2D:
         {
             bool allLevels         = (desc.Texture2D.MipLevels == std::numeric_limits<UINT>::max());
             unsigned int maxSrvMip = desc.Texture2D.MipLevels + desc.Texture2D.MostDetailedMip;
             maxSrvMip              = allLevels ? INT_MAX : maxSrvMip;
 
             unsigned mipMin = index.mipIndex;
             unsigned mipMax = INT_MAX;
 
-            return textureType == GL_TEXTURE_2D &&
+            return textureType == gl::TextureType::_2D &&
                    gl::RangeUI(mipMin, mipMax)
                        .intersects(gl::RangeUI(desc.Texture2D.MostDetailedMip, maxSrvMip));
         }
 
         case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
         {
             GLint layerIndex = index.layerIndex;
 
             bool allLevels = (desc.Texture2DArray.MipLevels == std::numeric_limits<UINT>::max());
             unsigned int maxSrvMip =
                 desc.Texture2DArray.MipLevels + desc.Texture2DArray.MostDetailedMip;
             maxSrvMip = allLevels ? INT_MAX : maxSrvMip;
 
             unsigned maxSlice = desc.Texture2DArray.FirstArraySlice + desc.Texture2DArray.ArraySize;
 
             // Cube maps can be mapped to Texture2DArray SRVs
-            return (textureType == GL_TEXTURE_2D_ARRAY || textureType == GL_TEXTURE_CUBE_MAP) &&
+            return (textureType == gl::TextureType::_2DArray ||
+                    textureType == gl::TextureType::CubeMap) &&
                    desc.Texture2DArray.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip &&
                    desc.Texture2DArray.FirstArraySlice <= static_cast<UINT>(layerIndex) &&
                    static_cast<UINT>(layerIndex) < maxSlice;
         }
 
         case D3D11_SRV_DIMENSION_TEXTURECUBE:
         {
             bool allLevels = (desc.TextureCube.MipLevels == std::numeric_limits<UINT>::max());
             unsigned int maxSrvMip = desc.TextureCube.MipLevels + desc.TextureCube.MostDetailedMip;
             maxSrvMip              = allLevels ? INT_MAX : maxSrvMip;
 
-            return textureType == GL_TEXTURE_CUBE_MAP &&
+            return textureType == gl::TextureType::CubeMap &&
                    desc.TextureCube.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip;
         }
 
         case D3D11_SRV_DIMENSION_TEXTURE3D:
         {
             bool allLevels         = (desc.Texture3D.MipLevels == std::numeric_limits<UINT>::max());
             unsigned int maxSrvMip = desc.Texture3D.MipLevels + desc.Texture3D.MostDetailedMip;
             maxSrvMip              = allLevels ? INT_MAX : maxSrvMip;
 
-            return textureType == GL_TEXTURE_3D && desc.Texture3D.MostDetailedMip <= mipLevel &&
-                   mipLevel < maxSrvMip;
+            return textureType == gl::TextureType::_3D &&
+                   desc.Texture3D.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip;
         }
         default:
             // We only handle the cases corresponding to valid image indexes
             UNIMPLEMENTED();
     }
 
     return false;
 }
@@ -173,16 +176,26 @@ void SortAttributesByLayout(const gl::Pr
 void UpdateUniformBuffer(ID3D11DeviceContext *deviceContext,
                          UniformStorage11 *storage,
                          const d3d11::Buffer *buffer)
 {
     deviceContext->UpdateSubresource(buffer->get(), 0, nullptr, storage->getDataPointer(0, 0), 0,
                                      0);
 }
 
+size_t GetReservedBufferCount(bool usesPointSpriteEmulation)
+{
+    return usesPointSpriteEmulation ? 1 : 0;
+}
+
+bool CullsEverything(const gl::State &glState)
+{
+    return (glState.getRasterizerState().cullFace &&
+            glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack);
+}
 }  // anonymous namespace
 
 // StateManager11::ViewCache Implementation.
 template <typename ViewType, typename DescType>
 StateManager11::ViewCache<ViewType, DescType>::ViewCache() : mHighestUsedView(0)
 {
 }
 
@@ -229,37 +242,33 @@ void StateManager11::ViewCache<ViewType,
     memset(&mCurrentViews[0], 0, sizeof(ViewRecord<DescType>) * mCurrentViews.size());
     mHighestUsedView = 0;
 }
 
 StateManager11::SRVCache *StateManager11::getSRVCache(gl::ShaderType shaderType)
 {
     switch (shaderType)
     {
-        case gl::SHADER_VERTEX:
+        case gl::ShaderType::Vertex:
             return &mCurVertexSRVs;
-        case gl::SHADER_FRAGMENT:
+        case gl::ShaderType::Fragment:
             return &mCurPixelSRVs;
-        case gl::SHADER_COMPUTE:
+        case gl::ShaderType::Compute:
             return &mCurComputeSRVs;
         default:
             UNREACHABLE();
             return &mCurVertexSRVs;
     }
 }
 
 // ShaderConstants11 implementation
 ShaderConstants11::ShaderConstants11()
-    : mVertexDirty(true),
-      mPixelDirty(true),
-      mComputeDirty(true),
-      mNumActiveVSSamplers(0),
-      mNumActivePSSamplers(0),
-      mNumActiveCSSamplers(0)
+    : mNumActiveVSSamplers(0), mNumActivePSSamplers(0), mNumActiveCSSamplers(0)
 {
+    mShaderConstantsDirty.set();
 }
 
 ShaderConstants11::~ShaderConstants11()
 {
 }
 
 void ShaderConstants11::init(const gl::Caps &caps)
 {
@@ -267,44 +276,44 @@ void ShaderConstants11::init(const gl::C
     mSamplerMetadataPS.resize(caps.maxTextureImageUnits);
     mSamplerMetadataCS.resize(caps.maxComputeTextureImageUnits);
 }
 
 size_t ShaderConstants11::getRequiredBufferSize(gl::ShaderType shaderType) const
 {
     switch (shaderType)
     {
-        case gl::SHADER_VERTEX:
+        case gl::ShaderType::Vertex:
             return sizeof(Vertex) + mSamplerMetadataVS.size() * sizeof(SamplerMetadata);
-        case gl::SHADER_FRAGMENT:
+        case gl::ShaderType::Fragment:
             return sizeof(Pixel) + mSamplerMetadataPS.size() * sizeof(SamplerMetadata);
-        case gl::SHADER_COMPUTE:
+        case gl::ShaderType::Compute:
             return sizeof(Compute) + mSamplerMetadataCS.size() * sizeof(SamplerMetadata);
         default:
             UNREACHABLE();
             return 0;
     }
 }
 
 void ShaderConstants11::markDirty()
 {
-    mVertexDirty         = true;
-    mPixelDirty          = true;
-    mComputeDirty        = true;
+    mShaderConstantsDirty.set();
     mNumActiveVSSamplers = 0;
     mNumActivePSSamplers = 0;
     mNumActiveCSSamplers = 0;
 }
 
 bool ShaderConstants11::updateSamplerMetadata(SamplerMetadata *data, const gl::Texture &texture)
 {
     bool dirty             = false;
     unsigned int baseLevel = texture.getTextureState().getEffectiveBaseLevel();
-    GLenum sizedFormat =
-        texture.getFormat(texture.getTarget(), baseLevel).info->sizedInternalFormat;
+    gl::TextureTarget target = (texture.getType() == gl::TextureType::CubeMap)
+                                   ? gl::kCubeMapTextureTargetMin
+                                   : gl::NonCubeTextureTypeToTarget(texture.getType());
+    GLenum sizedFormat = texture.getFormat(target, baseLevel).info->sizedInternalFormat;
     if (data->baseLevel != static_cast<int>(baseLevel))
     {
         data->baseLevel = static_cast<int>(baseLevel);
         dirty           = true;
     }
 
     // Some metadata is needed only for integer textures. We avoid updating the constant buffer
     // unnecessarily by changing the data only in case the texture is an integer texture and
@@ -378,34 +387,34 @@ bool ShaderConstants11::updateSamplerMet
 
 void ShaderConstants11::setComputeWorkGroups(GLuint numGroupsX,
                                              GLuint numGroupsY,
                                              GLuint numGroupsZ)
 {
     mCompute.numWorkGroups[0] = numGroupsX;
     mCompute.numWorkGroups[1] = numGroupsY;
     mCompute.numWorkGroups[2] = numGroupsZ;
-    mComputeDirty             = true;
+    mShaderConstantsDirty.set(gl::ShaderType::Compute);
 }
 
 void ShaderConstants11::setMultiviewWriteToViewportIndex(GLfloat index)
 {
     mVertex.multiviewWriteToViewportIndex = index;
-    mVertexDirty                          = true;
     mPixel.multiviewWriteToViewportIndex  = index;
-    mPixelDirty                           = true;
+    mShaderConstantsDirty.set(gl::ShaderType::Vertex);
+    mShaderConstantsDirty.set(gl::ShaderType::Fragment);
 }
 
 void ShaderConstants11::onViewportChange(const gl::Rectangle &glViewport,
                                          const D3D11_VIEWPORT &dxViewport,
                                          bool is9_3,
                                          bool presentPathFast)
 {
-    mVertexDirty = true;
-    mPixelDirty  = true;
+    mShaderConstantsDirty.set(gl::ShaderType::Vertex);
+    mShaderConstantsDirty.set(gl::ShaderType::Fragment);
 
     // On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders
     // using viewAdjust (like the D3D9 renderer).
     if (is9_3)
     {
         mVertex.viewAdjust[0] = static_cast<float>((glViewport.width - dxViewport.Width) +
                                                    2 * (glViewport.x - dxViewport.TopLeftX)) /
                                 dxViewport.Width;
@@ -452,29 +461,29 @@ void ShaderConstants11::onViewportChange
 }
 
 void ShaderConstants11::onSamplerChange(gl::ShaderType shaderType,
                                         unsigned int samplerIndex,
                                         const gl::Texture &texture)
 {
     switch (shaderType)
     {
-        case gl::SHADER_VERTEX:
+        case gl::ShaderType::Vertex:
             if (updateSamplerMetadata(&mSamplerMetadataVS[samplerIndex], texture))
             {
                 mNumActiveVSSamplers = 0;
             }
             break;
-        case gl::SHADER_FRAGMENT:
+        case gl::ShaderType::Fragment:
             if (updateSamplerMetadata(&mSamplerMetadataPS[samplerIndex], texture))
             {
                 mNumActivePSSamplers = 0;
             }
             break;
-        case gl::SHADER_COMPUTE:
+        case gl::ShaderType::Compute:
             if (updateSamplerMetadata(&mSamplerMetadataCS[samplerIndex], texture))
             {
                 mNumActiveCSSamplers = 0;
             }
             break;
         default:
             UNREACHABLE();
             break;
@@ -492,38 +501,41 @@ gl::Error ShaderConstants11::updateBuffe
     const uint8_t *samplerData = nullptr;
 
     // Re-upload the sampler meta-data if the current program uses more samplers
     // than we previously uploaded.
     int numSamplers = programD3D.getUsedSamplerRange(shaderType);
 
     switch (shaderType)
     {
-        case gl::SHADER_VERTEX:
-            dirty                   = mVertexDirty || (mNumActiveVSSamplers < numSamplers);
+        case gl::ShaderType::Vertex:
+            dirty = mShaderConstantsDirty[gl::ShaderType::Vertex] ||
+                    (mNumActiveVSSamplers < numSamplers);
             dataSize                = sizeof(Vertex);
             data                    = reinterpret_cast<const uint8_t *>(&mVertex);
             samplerData             = reinterpret_cast<const uint8_t *>(mSamplerMetadataVS.data());
-            mVertexDirty            = false;
+            mShaderConstantsDirty.set(gl::ShaderType::Vertex, false);
             mNumActiveVSSamplers    = numSamplers;
             break;
-        case gl::SHADER_FRAGMENT:
-            dirty                   = mPixelDirty || (mNumActivePSSamplers < numSamplers);
+        case gl::ShaderType::Fragment:
+            dirty = mShaderConstantsDirty[gl::ShaderType::Fragment] ||
+                    (mNumActivePSSamplers < numSamplers);
             dataSize                = sizeof(Pixel);
             data                    = reinterpret_cast<const uint8_t *>(&mPixel);
             samplerData             = reinterpret_cast<const uint8_t *>(mSamplerMetadataPS.data());
-            mPixelDirty             = false;
+            mShaderConstantsDirty.set(gl::ShaderType::Fragment, false);
             mNumActivePSSamplers    = numSamplers;
             break;
-        case gl::SHADER_COMPUTE:
-            dirty                   = mComputeDirty || (mNumActiveCSSamplers < numSamplers);
+        case gl::ShaderType::Compute:
+            dirty = mShaderConstantsDirty[gl::ShaderType::Compute] ||
+                    (mNumActiveCSSamplers < numSamplers);
             dataSize                = sizeof(Compute);
             data                    = reinterpret_cast<const uint8_t *>(&mCompute);
             samplerData             = reinterpret_cast<const uint8_t *>(mSamplerMetadataCS.data());
-            mComputeDirty           = false;
+            mShaderConstantsDirty.set(gl::ShaderType::Compute, false);
             mNumActiveCSSamplers    = numSamplers;
             break;
         default:
             UNREACHABLE();
             break;
     }
 
     ASSERT(driverConstantBuffer.valid());
@@ -567,30 +579,29 @@ StateManager11::StateManager11(Renderer1
       mCurFar(0.0f),
       mViewportBounds(),
       mRenderTargetIsDirty(true),
       mCurPresentPathFastEnabled(false),
       mCurPresentPathFastColorBufferHeight(0),
       mDirtyCurrentValueAttribs(),
       mCurrentValueAttribs(),
       mCurrentInputLayout(),
-      mInputLayoutIsDirty(false),
-      mVertexAttribsNeedTranslation(false),
       mDirtyVertexBufferRange(gl::MAX_VERTEX_ATTRIBS, 0),
       mCurrentPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED),
+      mLastAppliedDrawMode(GL_INVALID_INDEX),
+      mCurrentMinimumDrawCount(0),
       mDirtySwizzles(false),
       mAppliedIB(nullptr),
       mAppliedIBFormat(DXGI_FORMAT_UNKNOWN),
       mAppliedIBOffset(0),
       mIndexBufferIsDirty(false),
       mVertexDataManager(renderer),
       mIndexDataManager(renderer),
       mIsMultiviewEnabled(false),
-      mEmptySerial(mRenderer->generateSerial()),
-      mIsTransformFeedbackCurrentlyActiveUnpaused(false)
+      mEmptySerial(mRenderer->generateSerial())
 {
     mCurBlendState.blend                 = false;
     mCurBlendState.sourceBlendRGB        = GL_ONE;
     mCurBlendState.destBlendRGB          = GL_ZERO;
     mCurBlendState.sourceBlendAlpha      = GL_ONE;
     mCurBlendState.destBlendAlpha        = GL_ZERO;
     mCurBlendState.blendEquationRGB      = GL_FUNC_ADD;
     mCurBlendState.blendEquationAlpha    = GL_FUNC_ADD;
@@ -652,39 +663,39 @@ void StateManager11::setShaderResourceIn
     const ViewRecord<D3D11_SHADER_RESOURCE_VIEW_DESC> &record = (*currentSRVs)[resourceSlot];
 
     if (record.view != reinterpret_cast<uintptr_t>(srv))
     {
         ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
         ID3D11ShaderResourceView *srvPtr = srv ? srv->get() : nullptr;
         switch (shaderType)
         {
-            case gl::SHADER_VERTEX:
+            case gl::ShaderType::Vertex:
                 deviceContext->VSSetShaderResources(resourceSlot, 1, &srvPtr);
                 break;
-            case gl::SHADER_FRAGMENT:
+            case gl::ShaderType::Fragment:
                 deviceContext->PSSetShaderResources(resourceSlot, 1, &srvPtr);
                 break;
-            case gl::SHADER_COMPUTE:
+            case gl::ShaderType::Compute:
                 deviceContext->CSSetShaderResources(resourceSlot, 1, &srvPtr);
                 break;
             default:
                 UNREACHABLE();
         }
 
         currentSRVs->update(resourceSlot, srvPtr);
     }
 }
 
 template <typename UAVType>
 void StateManager11::setUnorderedAccessViewInternal(gl::ShaderType shaderType,
                                                     UINT resourceSlot,
                                                     const UAVType *uav)
 {
-    ASSERT(shaderType == gl::SHADER_COMPUTE);
+    ASSERT(shaderType == gl::ShaderType::Compute);
     ASSERT(static_cast<size_t>(resourceSlot) < mCurComputeUAVs.size());
     const ViewRecord<D3D11_UNORDERED_ACCESS_VIEW_DESC> &record = mCurComputeUAVs[resourceSlot];
 
     if (record.view != reinterpret_cast<uintptr_t>(uav))
     {
         auto deviceContext                = mRenderer->getDeviceContext();
         ID3D11UnorderedAccessView *uavPtr = uav ? uav->get() : nullptr;
         deviceContext->CSSetUnorderedAccessViews(resourceSlot, 1, &uavPtr, nullptr);
@@ -739,36 +750,36 @@ gl::Error StateManager11::updateStateFor
     mShaderConstants.setComputeWorkGroups(numGroupsX, numGroupsY, numGroupsZ);
 
     // TODO(jmadill): Use dirty bits.
     const auto &glState = context->getGLState();
     auto *programD3D    = GetImplAs<ProgramD3D>(glState.getProgram());
     programD3D->updateSamplerMapping();
 
     // TODO(jmadill): Use dirty bits.
-    ANGLE_TRY(generateSwizzlesForShader(context, gl::SHADER_COMPUTE));
+    ANGLE_TRY(generateSwizzlesForShader(context, gl::ShaderType::Compute));
 
     // TODO(jmadill): More complete implementation.
     ANGLE_TRY(syncTexturesForCompute(context));
 
     // TODO(Xinghua): applyUniformBuffers for compute shader.
 
     return gl::NoError();
 }
 
 void StateManager11::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits)
 {
     if (!dirtyBits.any())
     {
         return;
     }
 
-    const auto &state = context->getGLState();
-
-    for (auto dirtyBit : dirtyBits)
+    const gl::State &state = context->getGLState();
+
+    for (size_t dirtyBit : dirtyBits)
     {
         switch (dirtyBit)
         {
             case gl::State::DIRTY_BIT_BLEND_EQUATIONS:
             {
                 const gl::BlendState &blendState = state.getBlendState();
                 if (blendState.blendEquationRGB != mCurBlendState.blendEquationRGB ||
                     blendState.blendEquationAlpha != mCurBlendState.blendEquationAlpha)
@@ -910,28 +921,31 @@ void StateManager11::syncState(const gl:
                     mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
                 }
                 break;
             }
             case gl::State::DIRTY_BIT_CULL_FACE_ENABLED:
                 if (state.getRasterizerState().cullFace != mCurRasterState.cullFace)
                 {
                     mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
+                    mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
                 }
                 break;
             case gl::State::DIRTY_BIT_CULL_FACE:
                 if (state.getRasterizerState().cullMode != mCurRasterState.cullMode)
                 {
                     mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
+                    mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
                 }
                 break;
             case gl::State::DIRTY_BIT_FRONT_FACE:
                 if (state.getRasterizerState().frontFace != mCurRasterState.frontFace)
                 {
                     mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
+                    mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
                 }
                 break;
             case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED:
                 if (state.getRasterizerState().polygonOffsetFill !=
                     mCurRasterState.polygonOffsetFill)
                 {
                     mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
                 }
@@ -991,48 +1005,50 @@ void StateManager11::syncState(const gl:
                 break;
             case gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING:
                 invalidateVertexBuffer();
                 // Force invalidate the current value attributes, since the VertexArray11 keeps an
                 // internal cache of TranslatedAttributes, and they CurrentValue attributes are
                 // owned by the StateManager11/Context.
                 mDirtyCurrentValueAttribs.set();
                 // Invalidate the cached index buffer.
-                mIndexBufferIsDirty = true;
+                invalidateIndexBuffer();
                 break;
             case gl::State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS:
                 invalidateProgramUniformBuffers();
                 break;
             case gl::State::DIRTY_BIT_TEXTURE_BINDINGS:
                 invalidateTexturesAndSamplers();
                 break;
             case gl::State::DIRTY_BIT_SAMPLER_BINDINGS:
                 invalidateTexturesAndSamplers();
                 break;
+            case gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING:
+                invalidateTransformFeedback();
+                break;
             case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE:
             {
-                mInternalDirtyBits.set(DIRTY_BIT_SHADERS);
+                mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
+                invalidateShaders();
                 invalidateVertexBuffer();
                 invalidateRenderTarget();
                 invalidateTexturesAndSamplers();
                 invalidateProgramUniforms();
                 invalidateProgramUniformBuffers();
                 invalidateDriverUniforms();
-                gl::VertexArray *vao = state.getVertexArray();
-                if (mIsMultiviewEnabled && vao != nullptr)
+                if (mIsMultiviewEnabled)
                 {
+                    gl::VertexArray *vao = state.getVertexArray();
+                    ASSERT(vao);
                     // If ANGLE_multiview is enabled, the attribute divisor has to be updated for
                     // each binding.
                     VertexArray11 *vao11       = GetImplAs<VertexArray11>(vao);
                     const gl::Program *program = state.getProgram();
-                    int numViews               = 1;
-                    if (program != nullptr && program->usesMultiview())
-                    {
-                        numViews = program->getNumViews();
-                    }
+                    ASSERT(program);
+                    int numViews = program->usesMultiview() ? program->getNumViews() : 1;
                     vao11->markAllAttributeDivisorsForAdjustment(numViews);
                 }
                 break;
             }
             case gl::State::DIRTY_BIT_CURRENT_VALUES:
             {
                 for (auto attribIndex : state.getAndResetDirtyCurrentValues())
                 {
@@ -1139,61 +1155,72 @@ gl::Error StateManager11::syncDepthStenc
     // get the maximum size of the stencil ref
     unsigned int maxStencil = 0;
     if (mCurDepthStencilState.stencilTest && mCurStencilSize > 0)
     {
         maxStencil = (1 << mCurStencilSize) - 1;
     }
     ASSERT((mCurDepthStencilState.stencilWritemask & maxStencil) ==
            (mCurDepthStencilState.stencilBackWritemask & maxStencil));
-    ASSERT(mCurStencilRef == mCurStencilBackRef);
+    ASSERT(gl::clamp(mCurStencilRef, 0, static_cast<int>(maxStencil)) ==
+           gl::clamp(mCurStencilBackRef, 0, static_cast<int>(maxStencil)));
     ASSERT((mCurDepthStencilState.stencilMask & maxStencil) ==
            (mCurDepthStencilState.stencilBackMask & maxStencil));
 
     gl::DepthStencilState modifiedGLState = glState.getDepthStencilState();
 
     ASSERT(mCurDisableDepth.valid() && mCurDisableStencil.valid());
 
     if (mCurDisableDepth.value())
     {
         modifiedGLState.depthTest = false;
         modifiedGLState.depthMask = false;
     }
 
     if (mCurDisableStencil.value())
     {
-        modifiedGLState.stencilWritemask     = 0;
+        modifiedGLState.stencilTest = false;
+    }
+    if (!modifiedGLState.stencilTest)
+    {
+        modifiedGLState.stencilWritemask = 0;
         modifiedGLState.stencilBackWritemask = 0;
-        modifiedGLState.stencilTest          = false;
     }
 
+    // If STENCIL_TEST is disabled in glState, stencil testing and writing should be disabled.
+    // Verify that's true in the modifiedGLState so it is propagated to d3dState.
+    ASSERT(glState.getDepthStencilState().stencilTest ||
+           (!modifiedGLState.stencilTest && modifiedGLState.stencilWritemask == 0 &&
+            modifiedGLState.stencilBackWritemask == 0));
+
     const d3d11::DepthStencilState *d3dState = nullptr;
     ANGLE_TRY(mRenderer->getDepthStencilState(modifiedGLState, &d3dState));
     ASSERT(d3dState);
 
     // Max D3D11 stencil reference value is 0xFF,
     // corresponding to the max 8 bits in a stencil buffer
     // GL specifies we should clamp the ref value to the
     // nearest bit depth when doing stencil ops
     static_assert(D3D11_DEFAULT_STENCIL_READ_MASK == 0xFF,
                   "Unexpected value of D3D11_DEFAULT_STENCIL_READ_MASK");
     static_assert(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF,
                   "Unexpected value of D3D11_DEFAULT_STENCIL_WRITE_MASK");
-    UINT dxStencilRef = std::min<UINT>(mCurStencilRef, 0xFFu);
+    UINT dxStencilRef = static_cast<UINT>(gl::clamp(mCurStencilRef, 0, 0xFF));
 
     mRenderer->getDeviceContext()->OMSetDepthStencilState(d3dState->get(), dxStencilRef);
 
     return gl::NoError();
 }
 
-gl::Error StateManager11::syncRasterizerState(const gl::Context *context, bool pointDrawMode)
+gl::Error StateManager11::syncRasterizerState(const gl::Context *context,
+                                              const gl::DrawCallParams &drawCallParams)
 {
     // TODO: Remove pointDrawMode and multiSample from gl::RasterizerState.
     gl::RasterizerState rasterState = context->getGLState().getRasterizerState();
-    rasterState.pointDrawMode       = pointDrawMode;
+    rasterState.pointDrawMode       = (drawCallParams.mode() == GL_POINTS);
     rasterState.multiSample         = mCurRasterState.multiSample;
 
     ID3D11RasterizerState *dxRasterState = nullptr;
 
     if (mCurPresentPathFastEnabled)
     {
         gl::RasterizerState modifiedRasterState = rasterState;
 
@@ -1426,19 +1453,19 @@ void StateManager11::invalidateBoundView
     invalidateRenderTarget();
 }
 
 void StateManager11::invalidateVertexBuffer()
 {
     unsigned int limit = std::min<unsigned int>(mRenderer->getNativeCaps().maxVertexAttributes,
                                                 gl::MAX_VERTEX_ATTRIBS);
     mDirtyVertexBufferRange = gl::RangeUI(0, limit);
-    mInputLayoutIsDirty     = true;
+    invalidateInputLayout();
+    invalidateShaders();
     mInternalDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_ATTRIBS);
-    invalidateVertexAttributeTranslation();
 }
 
 void StateManager11::invalidateViewport(const gl::Context *context)
 {
     mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE);
 
     // Viewport affects the driver constants.
     invalidateDriverUniforms();
@@ -1489,16 +1516,35 @@ void StateManager11::invalidateConstantB
     }
 }
 
 void StateManager11::invalidateShaders()
 {
     mInternalDirtyBits.set(DIRTY_BIT_SHADERS);
 }
 
+void StateManager11::invalidateTransformFeedback()
+{
+    // Transform feedback affects the stream-out geometry shader.
+    invalidateShaders();
+    mInternalDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK);
+    // syncPrimitiveTopology checks the transform feedback state.
+    mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
+}
+
+void StateManager11::invalidateInputLayout()
+{
+    mInternalDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS_AND_INPUT_LAYOUT);
+}
+
+void StateManager11::invalidateIndexBuffer()
+{
+    mIndexBufferIsDirty = true;
+}
+
 void StateManager11::setRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv)
 {
     if ((rtv && unsetConflictingView(rtv)) || (dsv && unsetConflictingView(dsv)))
     {
         mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
     }
 
     mRenderer->getDeviceContext()->OMSetRenderTargets(1, &rtv, dsv);
@@ -1525,21 +1571,16 @@ void StateManager11::setRenderTargets(ID
     {
         mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
     }
 
     mRenderer->getDeviceContext()->OMSetRenderTargets(numRTVs, (numRTVs > 0) ? rtvs : nullptr, dsv);
     mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
 }
 
-void StateManager11::invalidateVertexAttributeTranslation()
-{
-    mVertexAttribsNeedTranslation = true;
-}
-
 void StateManager11::onBeginQuery(Query11 *query)
 {
     mCurrentQueries.insert(query);
 }
 
 void StateManager11::onDeleteQueryObject(Query11 *query)
 {
     mCurrentQueries.erase(query);
@@ -1581,27 +1622,27 @@ gl::Error StateManager11::clearSRVs(gl::
     if (clearRange.empty())
     {
         return gl::NoError();
     }
 
     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
     switch (shaderType)
     {
-        case gl::SHADER_VERTEX:
+        case gl::ShaderType::Vertex:
             deviceContext->VSSetShaderResources(static_cast<unsigned int>(clearRange.low()),
                                                 static_cast<unsigned int>(clearRange.length()),
                                                 &mNullSRVs[0]);
             break;
-        case gl::SHADER_FRAGMENT:
+        case gl::ShaderType::Fragment:
             deviceContext->PSSetShaderResources(static_cast<unsigned int>(clearRange.low()),
                                                 static_cast<unsigned int>(clearRange.length()),
                                                 &mNullSRVs[0]);
             break;
-        case gl::SHADER_COMPUTE:
+        case gl::ShaderType::Compute:
             deviceContext->CSSetShaderResources(static_cast<unsigned int>(clearRange.low()),
                                                 static_cast<unsigned int>(clearRange.length()),
                                                 &mNullSRVs[0]);
             break;
         default:
             UNREACHABLE();
             break;
     }
@@ -1611,17 +1652,17 @@ gl::Error StateManager11::clearSRVs(gl::
         currentSRVs->update(samplerIndex, nullptr);
     }
 
     return gl::NoError();
 }
 
 gl::Error StateManager11::clearUAVs(gl::ShaderType shaderType, size_t rangeStart, size_t rangeEnd)
 {
-    ASSERT(shaderType == gl::SHADER_COMPUTE);
+    ASSERT(shaderType == gl::ShaderType::Compute);
     if (rangeStart == rangeEnd)
     {
         return gl::NoError();
     }
 
     gl::Range<size_t> clearRange(rangeStart, std::min(rangeEnd, mCurComputeUAVs.highestUsed()));
     if (clearRange.empty())
     {
@@ -1639,18 +1680,18 @@ gl::Error StateManager11::clearUAVs(gl::
     }
 
     return gl::NoError();
 }
 
 bool StateManager11::unsetConflictingView(ID3D11View *view)
 {
     uintptr_t resource = reinterpret_cast<uintptr_t>(GetViewResource(view));
-    return unsetConflictingSRVs(gl::SHADER_VERTEX, resource, nullptr) ||
-           unsetConflictingSRVs(gl::SHADER_FRAGMENT, resource, nullptr);
+    return unsetConflictingSRVs(gl::ShaderType::Vertex, resource, nullptr) ||
+           unsetConflictingSRVs(gl::ShaderType::Fragment, resource, nullptr);
 }
 
 bool StateManager11::unsetConflictingSRVs(gl::ShaderType shaderType,
                                           uintptr_t resource,
                                           const gl::ImageIndex *index)
 {
     auto *currentSRVs = getSRVCache(shaderType);
 
@@ -1678,24 +1719,24 @@ void StateManager11::unsetConflictingAtt
 {
     // Unbind render target SRVs from the shader here to prevent D3D11 warnings.
     if (attachment->type() == GL_TEXTURE)
     {
         uintptr_t resourcePtr       = reinterpret_cast<uintptr_t>(resource);
         const gl::ImageIndex &index = attachment->getTextureImageIndex();
         // The index doesn't need to be corrected for the small compressed texture workaround
         // because a rendertarget is never compressed.
-        unsetConflictingSRVs(gl::SHADER_VERTEX, resourcePtr, &index);
-        unsetConflictingSRVs(gl::SHADER_FRAGMENT, resourcePtr, &index);
+        unsetConflictingSRVs(gl::ShaderType::Vertex, resourcePtr, &index);
+        unsetConflictingSRVs(gl::ShaderType::Fragment, resourcePtr, &index);
     }
     else if (attachment->type() == GL_FRAMEBUFFER_DEFAULT)
     {
         uintptr_t resourcePtr = reinterpret_cast<uintptr_t>(resource);
-        unsetConflictingSRVs(gl::SHADER_VERTEX, resourcePtr, nullptr);
-        unsetConflictingSRVs(gl::SHADER_FRAGMENT, resourcePtr, nullptr);
+        unsetConflictingSRVs(gl::ShaderType::Vertex, resourcePtr, nullptr);
+        unsetConflictingSRVs(gl::ShaderType::Fragment, resourcePtr, nullptr);
     }
 }
 
 gl::Error StateManager11::initialize(const gl::Caps &caps, const gl::Extensions &extensions)
 {
     mCurVertexSRVs.initialize(caps.maxVertexTextureImageUnits);
     mCurPixelSRVs.initialize(caps.maxTextureImageUnits);
 
@@ -1736,32 +1777,34 @@ void StateManager11::deinitialize()
     mCurrentValueAttribs.clear();
     mInputLayoutCache.clear();
     mVertexDataManager.deinitialize();
     mIndexDataManager.deinitialize();
 
     mDriverConstantBufferVS.reset();
     mDriverConstantBufferPS.reset();
     mDriverConstantBufferCS.reset();
+
+    mPointSpriteVertexBuffer.reset();
+    mPointSpriteIndexBuffer.reset();
 }
 
 gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer)
 {
     Framebuffer11 *framebuffer11 = GetImplAs<Framebuffer11>(framebuffer);
 
     // Applies the render target surface, depth stencil surface, viewport rectangle and
     // scissor rectangle to the renderer
-    ASSERT(framebuffer && !framebuffer->hasAnyDirtyBit() && framebuffer->cachedComplete());
+    ASSERT(framebuffer && !framebuffer->hasAnyDirtyBit());
 
     // Check for zero-sized default framebuffer, which is a special case.
     // in this case we do not wish to modify any state and just silently return false.
     // this will not report any gl error but will cause the calling method to return.
     if (framebuffer->id() == 0)
     {
-        ASSERT(!framebuffer11->hasAnyInternalDirtyBit());
         const gl::Extents &size = framebuffer->getFirstColorbuffer()->getSize();
         if (size.width == 0 || size.height == 0)
         {
             return gl::NoError();
         }
     }
 
     RTVArray framebufferRTVs = {{}};
@@ -1825,16 +1868,18 @@ gl::Error StateManager11::syncFramebuffe
 
     return gl::NoError();
 }
 
 void StateManager11::invalidateCurrentValueAttrib(size_t attribIndex)
 {
     mDirtyCurrentValueAttribs.set(attribIndex);
     mInternalDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_ATTRIBS);
+    invalidateInputLayout();
+    invalidateShaders();
 }
 
 gl::Error StateManager11::syncCurrentValueAttribs(const gl::State &glState)
 {
     const auto &activeAttribsMask  = glState.getProgram()->getActiveAttribLocationsMask();
     const auto &dirtyActiveAttribs = (activeAttribsMask & mDirtyCurrentValueAttribs);
 
     if (!dirtyActiveAttribs.any())
@@ -1854,78 +1899,74 @@ gl::Error StateManager11::syncCurrentVal
         const auto *attrib                   = &vertexAttributes[attribIndex];
         const auto &currentValue             = glState.getVertexAttribCurrentValue(attribIndex);
         TranslatedAttribute *currentValueAttrib = &mCurrentValueAttribs[attribIndex];
         currentValueAttrib->currentValueType = currentValue.Type;
         currentValueAttrib->attribute        = attrib;
         currentValueAttrib->binding          = &vertexBindings[attrib->bindingIndex];
 
         mDirtyVertexBufferRange.extend(static_cast<unsigned int>(attribIndex));
-        mInputLayoutIsDirty = true;
 
         ANGLE_TRY(mVertexDataManager.storeCurrentValue(currentValue, currentValueAttrib,
                                                        static_cast<size_t>(attribIndex)));
     }
 
     return gl::NoError();
 }
 
 void StateManager11::setInputLayout(const d3d11::InputLayout *inputLayout)
 {
+    if (setInputLayoutInternal(inputLayout))
+    {
+        invalidateInputLayout();
+    }
+}
+
+bool StateManager11::setInputLayoutInternal(const d3d11::InputLayout *inputLayout)
+{
     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
     if (inputLayout == nullptr)
     {
         if (!mCurrentInputLayout.empty())
         {
             deviceContext->IASetInputLayout(nullptr);
             mCurrentInputLayout.clear();
-            mInputLayoutIsDirty = true;
+            return true;
         }
     }
     else if (inputLayout->getSerial() != mCurrentInputLayout)
     {
         deviceContext->IASetInputLayout(inputLayout->get());
         mCurrentInputLayout = inputLayout->getSerial();
-        mInputLayoutIsDirty = true;
+        return true;
     }
+
+    return false;
 }
 
 bool StateManager11::queueVertexBufferChange(size_t bufferIndex,
                                              ID3D11Buffer *buffer,
                                              UINT stride,
                                              UINT offset)
 {
     if (buffer != mCurrentVertexBuffers[bufferIndex] ||
         stride != mCurrentVertexStrides[bufferIndex] ||
         offset != mCurrentVertexOffsets[bufferIndex])
     {
-        mInputLayoutIsDirty = true;
         mDirtyVertexBufferRange.extend(static_cast<unsigned int>(bufferIndex));
 
         mCurrentVertexBuffers[bufferIndex] = buffer;
         mCurrentVertexStrides[bufferIndex] = stride;
         mCurrentVertexOffsets[bufferIndex] = offset;
         return true;
     }
 
     return false;
 }
 
-bool StateManager11::queueVertexOffsetChange(size_t bufferIndex, UINT offsetOnly)
-{
-    if (offsetOnly != mCurrentVertexOffsets[bufferIndex])
-    {
-        mInputLayoutIsDirty = true;
-        mDirtyVertexBufferRange.extend(static_cast<unsigned int>(bufferIndex));
-        mCurrentVertexOffsets[bufferIndex] = offsetOnly;
-        return true;
-    }
-    return false;
-}
-
 void StateManager11::applyVertexBufferChanges()
 {
     if (mDirtyVertexBufferRange.empty())
     {
         return;
     }
 
     ASSERT(mDirtyVertexBufferRange.high() <= gl::MAX_VERTEX_ATTRIBS);
@@ -1940,90 +1981,91 @@ void StateManager11::applyVertexBufferCh
     mDirtyVertexBufferRange = gl::RangeUI(gl::MAX_VERTEX_ATTRIBS, 0);
 }
 
 void StateManager11::setSingleVertexBuffer(const d3d11::Buffer *buffer, UINT stride, UINT offset)
 {
     ID3D11Buffer *native = buffer ? buffer->get() : nullptr;
     if (queueVertexBufferChange(0, native, stride, offset))
     {
+        invalidateInputLayout();
         applyVertexBufferChanges();
     }
 }
 
-gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMode)
+gl::Error StateManager11::updateState(const gl::Context *context,
+                                      const gl::DrawCallParams &drawCallParams)
 {
-    const auto &glState = context->getGLState();
-    auto *programD3D    = GetImplAs<ProgramD3D>(glState.getProgram());
+    const gl::State &glState = context->getGLState();
+    auto *programD3D         = GetImplAs<ProgramD3D>(glState.getProgram());
 
     // TODO(jmadill): Use dirty bits.
     processFramebufferInvalidation(context);
 
     // TODO(jmadill): Use dirty bits.
     if (programD3D->updateSamplerMapping() == ProgramD3D::SamplerMapping::WasDirty)
     {
         invalidateTexturesAndSamplers();
     }
 
     // TODO(jmadill): Use dirty bits.
-    if (programD3D->areVertexUniformsDirty() || programD3D->areFragmentUniformsDirty())
+    if (programD3D->anyShaderUniformsDirty())
     {
         mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORMS);
     }
 
-    // Transform feedback affects the stream-out geometry shader.
-    // TODO(jmadill): Use dirty bits.
-    if (glState.isTransformFeedbackActiveUnpaused() != mIsTransformFeedbackCurrentlyActiveUnpaused)
-    {
-        mIsTransformFeedbackCurrentlyActiveUnpaused = glState.isTransformFeedbackActiveUnpaused();
-        invalidateShaders();
-    }
-
     // Swizzling can cause internal state changes with blit shaders.
     if (mDirtySwizzles)
     {
         ANGLE_TRY(generateSwizzles(context));
         mDirtySwizzles = false;
     }
 
     gl::Framebuffer *framebuffer = glState.getDrawFramebuffer();
     Framebuffer11 *framebuffer11 = GetImplAs<Framebuffer11>(framebuffer);
     ANGLE_TRY(framebuffer11->markAttachmentsDirty(context));
 
-    if (framebuffer11->hasAnyInternalDirtyBit())
-    {
-        ASSERT(framebuffer->id() != 0);
-        framebuffer11->syncInternalState(context);
-    }
-
-    bool pointDrawMode = (drawMode == GL_POINTS);
-    if (pointDrawMode != mCurRasterState.pointDrawMode)
-    {
-        mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
-
-        // Changing from points to not points (or vice-versa) affects the geometry shader.
-        invalidateShaders();
-    }
-
     // TODO(jiawei.shao@intel.com): This can be recomputed only on framebuffer or multisample mask
     // state changes.
     RenderTarget11 *firstRT = framebuffer11->getFirstRenderTarget();
     int samples             = (firstRT ? firstRT->getSamples() : 0);
     unsigned int sampleMask = GetBlendSampleMask(glState, samples);
     if (sampleMask != mCurSampleMask)
     {
         mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
     }
 
-    // Changing the vertex attribute state can affect the vertex shader.
-    gl::VertexArray *vao = glState.getVertexArray();
-    VertexArray11 *vao11 = GetImplAs<VertexArray11>(vao);
-    if (vao11->flushAttribUpdates(context))
+    // Changes in the draw call can affect the vertex buffer translations.
+    if (!mLastFirstVertex.valid() || mLastFirstVertex.value() != drawCallParams.firstVertex())
+    {
+        mLastFirstVertex = drawCallParams.firstVertex();
+        invalidateInputLayout();
+    }
+
+    VertexArray11 *vao11 = GetImplAs<VertexArray11>(glState.getVertexArray());
+    ANGLE_TRY(vao11->syncStateForDraw(context, drawCallParams));
+
+    if (drawCallParams.isDrawElements())
     {
-        mInternalDirtyBits.set(DIRTY_BIT_SHADERS);
+        ANGLE_TRY(applyIndexBuffer(context, drawCallParams));
+    }
+
+    if (mLastAppliedDrawMode != drawCallParams.mode())
+    {
+        mLastAppliedDrawMode = drawCallParams.mode();
+        mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
+
+        bool pointDrawMode = (drawCallParams.mode() == GL_POINTS);
+        if (pointDrawMode != mCurRasterState.pointDrawMode)
+        {
+            mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
+
+            // Changing from points to not points (or vice-versa) affects the geometry shader.
+            invalidateShaders();
+        }
     }
 
     auto dirtyBitsCopy = mInternalDirtyBits;
     mInternalDirtyBits.reset();
 
     for (auto dirtyBit : dirtyBitsCopy)
     {
         switch (dirtyBit)
@@ -2033,17 +2075,17 @@ gl::Error StateManager11::updateState(co
                 break;
             case DIRTY_BIT_VIEWPORT_STATE:
                 syncViewport(context);
                 break;
             case DIRTY_BIT_SCISSOR_STATE:
                 syncScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled());
                 break;
             case DIRTY_BIT_RASTERIZER_STATE:
-                ANGLE_TRY(syncRasterizerState(context, pointDrawMode));
+                ANGLE_TRY(syncRasterizerState(context, drawCallParams));
                 break;
             case DIRTY_BIT_BLEND_STATE:
                 ANGLE_TRY(syncBlendState(context, framebuffer, glState.getBlendState(),
                                          glState.getBlendColor(), sampleMask));
                 break;
             case DIRTY_BIT_DEPTH_STENCIL_STATE:
                 ANGLE_TRY(syncDepthStencilState(glState));
                 break;
@@ -2057,29 +2099,36 @@ gl::Error StateManager11::updateState(co
             case DIRTY_BIT_DRIVER_UNIFORMS:
                 // This must happen after viewport sync; the viewport affects builtin uniforms.
                 ANGLE_TRY(applyDriverUniforms(*programD3D));
                 break;
             case DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS:
                 ANGLE_TRY(syncUniformBuffers(context, programD3D));
                 break;
             case DIRTY_BIT_SHADERS:
-                ANGLE_TRY(syncProgram(context, drawMode));
+                ANGLE_TRY(syncProgram(context, drawCallParams.mode()));
                 break;
             case DIRTY_BIT_CURRENT_VALUE_ATTRIBS:
                 ANGLE_TRY(syncCurrentValueAttribs(glState));
                 break;
+            case DIRTY_BIT_TRANSFORM_FEEDBACK:
+                ANGLE_TRY(syncTransformFeedbackBuffers(context));
+                break;
+            case DIRTY_BIT_VERTEX_BUFFERS_AND_INPUT_LAYOUT:
+                ANGLE_TRY(syncVertexBuffersAndInputLayout(context, drawCallParams));
+                break;
+            case DIRTY_BIT_PRIMITIVE_TOPOLOGY:
+                syncPrimitiveTopology(glState, programD3D, drawCallParams.mode());
+                break;
             default:
                 UNREACHABLE();
                 break;
         }
     }
 
-    ANGLE_TRY(syncTransformFeedbackBuffers(context));
-
     // Check that we haven't set any dirty bits in the flushing of the dirty bits loop.
     ASSERT(mInternalDirtyBits.none());
 
     return gl::NoError();
 }
 
 void StateManager11::setShaderResourceShared(gl::ShaderType shaderType,
                                              UINT resourceSlot,
@@ -2098,20 +2147,33 @@ void StateManager11::setShaderResource(g
     setShaderResourceInternal(shaderType, resourceSlot, srv);
 
     // TODO(jmadill): Narrower dirty region.
     mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
 }
 
 void StateManager11::setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology)
 {
+    if (setPrimitiveTopologyInternal(primitiveTopology))
+    {
+        mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
+    }
+}
+
+bool StateManager11::setPrimitiveTopologyInternal(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology)
+{
     if (primitiveTopology != mCurrentPrimitiveTopology)
     {
         mRenderer->getDeviceContext()->IASetPrimitiveTopology(primitiveTopology);
         mCurrentPrimitiveTopology = primitiveTopology;
+        return true;
+    }
+    else
+    {
+        return false;
     }
 }
 
 void StateManager11::setDrawShaders(const d3d11::VertexShader *vertexShader,
                                     const d3d11::GeometryShader *geometryShader,
                                     const d3d11::PixelShader *pixelShader)
 {
     setVertexShader(vertexShader);
@@ -2297,17 +2359,17 @@ void StateManager11::setSimpleViewport(i
     mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE);
 }
 
 void StateManager11::setSimplePixelTextureAndSampler(const d3d11::SharedSRV &srv,
                                                      const d3d11::SamplerState &samplerState)
 {
     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
 
-    setShaderResourceInternal(gl::SHADER_FRAGMENT, 0, &srv);
+    setShaderResourceInternal(gl::ShaderType::Fragment, 0, &srv);
     deviceContext->PSSetSamplers(0, 1, samplerState.getPointer());
 
     mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
     mForceSetPixelSamplerStates[0] = true;
 }
 
 void StateManager11::setSimpleScissorRect(const gl::Rectangle &glRect)
 {
@@ -2326,17 +2388,17 @@ void StateManager11::setScissorRectD3D(c
 }
 
 // For each Direct3D sampler of either the pixel or vertex stage,
 // looks up the corresponding OpenGL texture image unit and texture type,
 // and sets the texture and its addressing/filtering state (or NULL when inactive).
 // Sampler mapping needs to be up-to-date on the program object before this is called.
 gl::Error StateManager11::applyTextures(const gl::Context *context, gl::ShaderType shaderType)
 {
-    ASSERT(shaderType != gl::SHADER_COMPUTE);
+    ASSERT(shaderType != gl::ShaderType::Compute);
     const auto &glState    = context->getGLState();
     const auto &caps       = context->getCaps();
     ProgramD3D *programD3D = GetImplAs<ProgramD3D>(glState.getProgram());
 
     ASSERT(!programD3D->isSamplerMappingDirty());
 
     // TODO(jmadill): Use the Program's sampler bindings.
     const auto &completeTextures = glState.getCompleteTextureCache();
@@ -2356,40 +2418,42 @@ gl::Error StateManager11::applyTextures(
             const gl::SamplerState &samplerState =
                 samplerObject ? samplerObject->getSamplerState() : texture->getSamplerState();
 
             ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, texture, samplerState));
             ANGLE_TRY(setTexture(context, shaderType, samplerIndex, texture));
         }
         else
         {
-            GLenum textureType = programD3D->getSamplerTextureType(shaderType, samplerIndex);
+            gl::TextureType textureType =
+                programD3D->getSamplerTextureType(shaderType, samplerIndex);
 
             // Texture is not sampler complete or it is in use by the framebuffer.  Bind the
             // incomplete texture.
             gl::Texture *incompleteTexture = nullptr;
             ANGLE_TRY(mRenderer->getIncompleteTexture(context, textureType, &incompleteTexture));
             ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, incompleteTexture,
                                       incompleteTexture->getSamplerState()));
             ANGLE_TRY(setTexture(context, shaderType, samplerIndex, incompleteTexture));
         }
     }
 
     // Set all the remaining textures to NULL
-    size_t samplerCount = (shaderType == gl::SHADER_FRAGMENT) ? caps.maxTextureImageUnits
-                                                              : caps.maxVertexTextureImageUnits;
+    size_t samplerCount = (shaderType == gl::ShaderType::Fragment)
+                              ? caps.maxTextureImageUnits
+                              : caps.maxVertexTextureImageUnits;
     ANGLE_TRY(clearSRVs(shaderType, samplerRange, samplerCount));
 
     return gl::NoError();
 }
 
 gl::Error StateManager11::syncTextures(const gl::Context *context)
 {
-    ANGLE_TRY(applyTextures(context, gl::SHADER_VERTEX));
-    ANGLE_TRY(applyTextures(context, gl::SHADER_FRAGMENT));
+    ANGLE_TRY(applyTextures(context, gl::ShaderType::Vertex));
+    ANGLE_TRY(applyTextures(context, gl::ShaderType::Fragment));
     return gl::NoError();
 }
 
 gl::Error StateManager11::setSamplerState(const gl::Context *context,
                                           gl::ShaderType type,
                                           int index,
                                           gl::Texture *texture,
                                           const gl::SamplerState &samplerState)
@@ -2399,17 +2463,17 @@ gl::Error StateManager11::setSamplerStat
     TextureD3D *textureD3D  = GetImplAs<TextureD3D>(texture);
     TextureStorage *storage = nullptr;
     ANGLE_TRY(textureD3D->getNativeTexture(context, &storage));
     ASSERT(storage);
 #endif  // !defined(NDEBUG)
 
     auto *deviceContext = mRenderer->getDeviceContext();
 
-    if (type == gl::SHADER_FRAGMENT)
+    if (type == gl::ShaderType::Fragment)
     {
         ASSERT(static_cast<unsigned int>(index) < mRenderer->getNativeCaps().maxTextureImageUnits);
 
         if (mForceSetPixelSamplerStates[index] ||
             memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
         {
             ID3D11SamplerState *dxSamplerState = nullptr;
             ANGLE_TRY(mRenderer->getSamplerState(samplerState, &dxSamplerState));
@@ -2417,17 +2481,17 @@ gl::Error StateManager11::setSamplerStat
             ASSERT(dxSamplerState != nullptr);
             deviceContext->PSSetSamplers(index, 1, &dxSamplerState);
 
             mCurPixelSamplerStates[index] = samplerState;
         }
 
         mForceSetPixelSamplerStates[index] = false;
     }
-    else if (type == gl::SHADER_VERTEX)
+    else if (type == gl::ShaderType::Vertex)
     {
         ASSERT(static_cast<unsigned int>(index) <
                mRenderer->getNativeCaps().maxVertexTextureImageUnits);
 
         if (mForceSetVertexSamplerStates[index] ||
             memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
         {
             ID3D11SamplerState *dxSamplerState = nullptr;
@@ -2436,17 +2500,17 @@ gl::Error StateManager11::setSamplerStat
             ASSERT(dxSamplerState != nullptr);
             deviceContext->VSSetSamplers(index, 1, &dxSamplerState);
 
             mCurVertexSamplerStates[index] = samplerState;
         }
 
         mForceSetVertexSamplerStates[index] = false;
     }
-    else if (type == gl::SHADER_COMPUTE)
+    else if (type == gl::ShaderType::Compute)
     {
         ASSERT(static_cast<unsigned int>(index) <
                mRenderer->getNativeCaps().maxComputeTextureImageUnits);
 
         if (mForceSetComputeSamplerStates[index] ||
             memcmp(&samplerState, &mCurComputeSamplerStates[index], sizeof(gl::SamplerState)) != 0)
         {
             ID3D11SamplerState *dxSamplerState = nullptr;
@@ -2471,17 +2535,17 @@ gl::Error StateManager11::setSamplerStat
     return gl::NoError();
 }
 
 gl::Error StateManager11::setTexture(const gl::Context *context,
                                      gl::ShaderType type,
                                      int index,
                                      gl::Texture *texture)
 {
-    ASSERT(type != gl::SHADER_COMPUTE);
+    ASSERT(type != gl::ShaderType::Compute);
     const d3d11::SharedSRV *textureSRV = nullptr;
 
     if (texture)
     {
         TextureD3D *textureImpl = GetImplAs<TextureD3D>(texture);
 
         TextureStorage *texStorage = nullptr;
         ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage));
@@ -2496,59 +2560,60 @@ gl::Error StateManager11::setTexture(con
         // If we get an invalid SRV here, something went wrong in the texture class and we're
         // unexpectedly missing the shader resource view.
         ASSERT(textureSRV->valid());
 
         textureImpl->resetDirty();
     }
 
     ASSERT(
-        (type == gl::SHADER_FRAGMENT &&
+        (type == gl::ShaderType::Fragment &&
          static_cast<unsigned int>(index) < mRenderer->getNativeCaps().maxTextureImageUnits) ||
-        (type == gl::SHADER_VERTEX &&
+        (type == gl::ShaderType::Vertex &&
          static_cast<unsigned int>(index) < mRenderer->getNativeCaps().maxVertexTextureImageUnits));
 
     setShaderResourceInternal(type, index, textureSRV);
     return gl::NoError();
 }
 
 gl::Error StateManager11::syncTexturesForCompute(const gl::Context *context)
 {
     const auto &glState    = context->getGLState();
     const auto &caps       = context->getCaps();
     ProgramD3D *programD3D = GetImplAs<ProgramD3D>(glState.getProgram());
 
     // TODO(xinghua.cao@intel.com): Implement sampler feature in compute shader.
-    unsigned int readonlyImageRange = programD3D->getUsedImageRange(gl::SHADER_COMPUTE, true);
+    unsigned int readonlyImageRange = programD3D->getUsedImageRange(gl::ShaderType::Compute, true);
     for (unsigned int readonlyImageIndex = 0; readonlyImageIndex < readonlyImageRange;
          readonlyImageIndex++)
     {
         GLint imageUnitIndex =
-            programD3D->getImageMapping(gl::SHADER_COMPUTE, readonlyImageIndex, true, caps);
+            programD3D->getImageMapping(gl::ShaderType::Compute, readonlyImageIndex, true, caps);
+        ASSERT(imageUnitIndex != -1);
+        const gl::ImageUnit &imageUnit = glState.getImageUnit(imageUnitIndex);
+        ANGLE_TRY(setTextureForImage(context, gl::ShaderType::Compute, readonlyImageIndex, true,
+                                     imageUnit));
+    }
+
+    unsigned int imageRange = programD3D->getUsedImageRange(gl::ShaderType::Compute, false);
+    for (unsigned int imageIndex = 0; imageIndex < imageRange; imageIndex++)
+    {
+        GLint imageUnitIndex =
+            programD3D->getImageMapping(gl::ShaderType::Compute, imageIndex, false, caps);
         ASSERT(imageUnitIndex != -1);
         const gl::ImageUnit &imageUnit = glState.getImageUnit(imageUnitIndex);
         ANGLE_TRY(
-            setTextureForImage(context, gl::SHADER_COMPUTE, readonlyImageIndex, true, imageUnit));
-    }
-
-    unsigned int imageRange = programD3D->getUsedImageRange(gl::SHADER_COMPUTE, false);
-    for (unsigned int imageIndex = 0; imageIndex < imageRange; imageIndex++)
-    {
-        GLint imageUnitIndex =
-            programD3D->getImageMapping(gl::SHADER_COMPUTE, imageIndex, false, caps);
-        ASSERT(imageUnitIndex != -1);
-        const gl::ImageUnit &imageUnit = glState.getImageUnit(imageUnitIndex);
-        ANGLE_TRY(setTextureForImage(context, gl::SHADER_COMPUTE, imageIndex, false, imageUnit));
+            setTextureForImage(context, gl::ShaderType::Compute, imageIndex, false, imageUnit));
     }
 
     // Set all the remaining textures to NULL
     size_t readonlyImageCount = caps.maxImageUnits;
     size_t imageCount         = caps.maxImageUnits;
-    ANGLE_TRY(clearSRVs(gl::SHADER_COMPUTE, readonlyImageRange, readonlyImageCount));
-    ANGLE_TRY(clearUAVs(gl::SHADER_COMPUTE, imageRange, imageCount));
+    ANGLE_TRY(clearSRVs(gl::ShaderType::Compute, readonlyImageRange, readonlyImageCount));
+    ANGLE_TRY(clearUAVs(gl::ShaderType::Compute, imageRange, imageCount));
 
     return gl::NoError();
 }
 
 gl::Error StateManager11::setTextureForImage(const gl::Context *context,
                                              gl::ShaderType type,
                                              int index,
                                              bool readonly,
@@ -2652,55 +2717,32 @@ gl::Error StateManager11::syncProgram(co
     setDrawShaders(vertexShader, geometryShader, pixelShader);
 
     // Explicitly clear the shaders dirty bit.
     mInternalDirtyBits.reset(DIRTY_BIT_SHADERS);
 
     return gl::NoError();
 }
 
-gl::Error StateManager11::applyVertexBuffer(const gl::Context *context,
-                                            GLenum mode,
-                                            const DrawCallVertexParams &vertexParams,
-                                            bool isIndexedRendering)
+gl::Error StateManager11::syncVertexBuffersAndInputLayout(const gl::Context *context,
+                                                          const gl::DrawCallParams &drawCallParams)
 {
-    const auto &state       = context->getGLState();
+    const gl::State &state             = context->getGLState();
     const gl::VertexArray *vertexArray = state.getVertexArray();
     VertexArray11 *vertexArray11       = GetImplAs<VertexArray11>(vertexArray);
 
-    if (mVertexAttribsNeedTranslation)
-    {
-        ANGLE_TRY(vertexArray11->updateDirtyAndDynamicAttribs(context, &mVertexDataManager,
-                                                              vertexParams));
-        mInputLayoutIsDirty = true;
-
-        // Determine if we need to update attribs on the next draw.
-        mVertexAttribsNeedTranslation = (vertexArray11->hasActiveDynamicAttrib(context));
-    }
-
-    if (!mLastFirstVertex.valid() || mLastFirstVertex.value() != vertexParams.firstVertex())
-    {
-        mLastFirstVertex    = vertexParams.firstVertex();
-        mInputLayoutIsDirty = true;
-    }
-
-    if (!mInputLayoutIsDirty)
-    {
-        return gl::NoError();
-    }
-
     const auto &vertexArrayAttribs = vertexArray11->getTranslatedAttribs();
     gl::Program *program           = state.getProgram();
 
     // Sort the attributes according to ensure we re-use similar input layouts.
     AttribIndexArray sortedSemanticIndices;
     SortAttributesByLayout(program, vertexArrayAttribs, mCurrentValueAttribs,
                            &sortedSemanticIndices, &mCurrentAttributes);
 
-    auto featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel;
+    D3D_FEATURE_LEVEL featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel;
 
     // If we are using FL 9_3, make sure the first attribute is not instanced
     if (featureLevel <= D3D_FEATURE_LEVEL_9_3 && !mCurrentAttributes.empty())
     {
         if (mCurrentAttributes[0]->divisor > 0)
         {
             Optional<size_t> firstNonInstancedIndex = FindFirstNonInstanced(mCurrentAttributes);
             if (firstNonInstancedIndex.valid())
@@ -2708,95 +2750,232 @@ gl::Error StateManager11::applyVertexBuf
                 size_t index = firstNonInstancedIndex.value();
                 std::swap(mCurrentAttributes[0], mCurrentAttributes[index]);
                 std::swap(sortedSemanticIndices[0], sortedSemanticIndices[index]);
             }
         }
     }
 
     // Update the applied input layout by querying the cache.
-    ANGLE_TRY(mInputLayoutCache.updateInputLayout(mRenderer, state, mCurrentAttributes, mode,
-                                                  sortedSemanticIndices, vertexParams));
+    const d3d11::InputLayout *inputLayout = nullptr;
+    ANGLE_TRY(mInputLayoutCache.getInputLayout(
+        mRenderer, state, mCurrentAttributes, sortedSemanticIndices, drawCallParams, &inputLayout));
+    setInputLayoutInternal(inputLayout);
 
     // Update the applied vertex buffers.
-    ANGLE_TRY(mInputLayoutCache.applyVertexBuffers(context, mCurrentAttributes, mode,
-                                                   vertexParams.firstVertex(), isIndexedRendering));
-
-    // InputLayoutCache::applyVertexBuffers calls through to the Bufer11 to get the native vertex
-    // buffer (ID3D11Buffer *). Because we allocate these buffers lazily, this will trigger
-    // allocation. This in turn will signal that the buffer is dirty. Since we just resolved the
-    // dirty-ness in VertexArray11::updateDirtyAndDynamicAttribs, this can make us do a needless
-    // update on the second draw call.
-    // Hence we clear the flags here, after we've applied vertex data, since we know everything
-    // is clean. This is a bit of a hack.
-    vertexArray11->clearDirtyAndPromoteDynamicAttribs(context, vertexParams);
-
-    mInputLayoutIsDirty = false;
+    ANGLE_TRY(applyVertexBuffers(context, drawCallParams));
+
+    return gl::NoError();
+}
+
+gl::Error StateManager11::applyVertexBuffers(const gl::Context *context,
+                                             const gl::DrawCallParams &drawCallParams)
+{
+    const gl::State &state = context->getGLState();
+    gl::Program *program   = state.getProgram();
+    ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
+
+    bool programUsesInstancedPointSprites =
+        programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation();
+    bool instancedPointSpritesActive =
+        programUsesInstancedPointSprites && (drawCallParams.mode() == GL_POINTS);
+
+    // Note that if we use instance emulation, we reserve the first buffer slot.
+    size_t reservedBuffers = GetReservedBufferCount(programUsesInstancedPointSprites);
+
+    for (size_t attribIndex = 0; attribIndex < (gl::MAX_VERTEX_ATTRIBS - reservedBuffers);
+         ++attribIndex)
+    {
+        ID3D11Buffer *buffer = nullptr;
+        UINT vertexStride    = 0;
+        UINT vertexOffset    = 0;
+
+        if (attribIndex < mCurrentAttributes.size())
+        {
+            const TranslatedAttribute &attrib = *mCurrentAttributes[attribIndex];
+            Buffer11 *bufferStorage = attrib.storage ? GetAs<Buffer11>(attrib.storage) : nullptr;
+
+            // If indexed pointsprite emulation is active, then we need to take a less efficent code
+            // path. Emulated indexed pointsprite rendering requires that the vertex buffers match
+            // exactly to the indices passed by the caller.  This could expand or shrink the vertex
+            // buffer depending on the number of points indicated by the index list or how many
+            // duplicates are found on the index list.
+            if (bufferStorage == nullptr)
+            {
+                ASSERT(attrib.vertexBuffer.get());
+                buffer = GetAs<VertexBuffer11>(attrib.vertexBuffer.get())->getBuffer().get();
+            }
+            else if (instancedPointSpritesActive && drawCallParams.isDrawElements())
+            {
+                VertexArray11 *vao11 = GetImplAs<VertexArray11>(state.getVertexArray());
+                ASSERT(vao11->isCachedIndexInfoValid());
+                TranslatedIndexData indexInfo = vao11->getCachedIndexInfo();
+                if (indexInfo.srcIndexData.srcBuffer != nullptr)
+                {
+                    const uint8_t *bufferData = nullptr;
+                    ANGLE_TRY(indexInfo.srcIndexData.srcBuffer->getData(context, &bufferData));
+                    ASSERT(bufferData != nullptr);
+
+                    ptrdiff_t offset =
+                        reinterpret_cast<ptrdiff_t>(indexInfo.srcIndexData.srcIndices);
+                    indexInfo.srcIndexData.srcBuffer  = nullptr;
+                    indexInfo.srcIndexData.srcIndices = bufferData + offset;
+                }
+
+                ANGLE_TRY_RESULT(
+                    bufferStorage->getEmulatedIndexedBuffer(context, &indexInfo.srcIndexData,
+                                                            attrib, drawCallParams.firstVertex()),
+                    buffer);
+
+                vao11->updateCachedIndexInfo(indexInfo);
+            }
+            else
+            {
+                ANGLE_TRY_RESULT(
+                    bufferStorage->getBuffer(context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK),
+                    buffer);
+            }
+
+            vertexStride = attrib.stride;
+            ANGLE_TRY_RESULT(attrib.computeOffset(drawCallParams.firstVertex()), vertexOffset);
+        }
+
+        size_t bufferIndex = reservedBuffers + attribIndex;
+
+        queueVertexBufferChange(bufferIndex, buffer, vertexStride, vertexOffset);
+    }
+
+    // Instanced PointSprite emulation requires two additional ID3D11Buffers. A vertex buffer needs
+    // to be created and added to the list of current buffers, strides and offsets collections.
+    // This buffer contains the vertices for a single PointSprite quad.
+    // An index buffer also needs to be created and applied because rendering instanced data on
+    // D3D11 FL9_3 requires DrawIndexedInstanced() to be used. Shaders that contain gl_PointSize and
+    // used without the GL_POINTS rendering mode require a vertex buffer because some drivers cannot
+    // handle missing vertex data and will TDR the system.
+    if (programUsesInstancedPointSprites)
+    {
+        constexpr UINT kPointSpriteVertexStride = sizeof(float) * 5;
+
+        if (!mPointSpriteVertexBuffer.valid())
+        {
+            static constexpr float kPointSpriteVertices[] = {
+                // Position        | TexCoord
+                -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, /* v0 */
+                -1.0f, 1.0f,  0.0f, 0.0f, 0.0f, /* v1 */
+                1.0f,  1.0f,  0.0f, 1.0f, 0.0f, /* v2 */
+                1.0f,  -1.0f, 0.0f, 1.0f, 1.0f, /* v3 */
+                -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, /* v4 */
+                1.0f,  1.0f,  0.0f, 1.0f, 0.0f, /* v5 */
+            };
+
+            D3D11_SUBRESOURCE_DATA vertexBufferData = {kPointSpriteVertices, 0, 0};
+            D3D11_BUFFER_DESC vertexBufferDesc;
+            vertexBufferDesc.ByteWidth           = sizeof(kPointSpriteVertices);
+            vertexBufferDesc.BindFlags           = D3D11_BIND_VERTEX_BUFFER;
+            vertexBufferDesc.Usage               = D3D11_USAGE_IMMUTABLE;
+            vertexBufferDesc.CPUAccessFlags      = 0;
+            vertexBufferDesc.MiscFlags           = 0;
+            vertexBufferDesc.StructureByteStride = 0;
+
+            ANGLE_TRY(mRenderer->allocateResource(vertexBufferDesc, &vertexBufferData,
+                                                  &mPointSpriteVertexBuffer));
+        }
+
+        // Set the stride to 0 if GL_POINTS mode is not being used to instruct the driver to avoid
+        // indexing into the vertex buffer.
+        UINT stride = instancedPointSpritesActive ? kPointSpriteVertexStride : 0;
+        queueVertexBufferChange(0, mPointSpriteVertexBuffer.get(), stride, 0);
+
+        if (!mPointSpriteIndexBuffer.valid())
+        {
+            // Create an index buffer and set it for pointsprite rendering
+            static constexpr unsigned short kPointSpriteIndices[] = {
+                0, 1, 2, 3, 4, 5,
+            };
+
+            D3D11_SUBRESOURCE_DATA indexBufferData = {kPointSpriteIndices, 0, 0};
+            D3D11_BUFFER_DESC indexBufferDesc;
+            indexBufferDesc.ByteWidth           = sizeof(kPointSpriteIndices);
+            indexBufferDesc.BindFlags           = D3D11_BIND_INDEX_BUFFER;
+            indexBufferDesc.Usage               = D3D11_USAGE_IMMUTABLE;
+            indexBufferDesc.CPUAccessFlags      = 0;
+            indexBufferDesc.MiscFlags           = 0;
+            indexBufferDesc.StructureByteStride = 0;
+
+            ANGLE_TRY(mRenderer->allocateResource(indexBufferDesc, &indexBufferData,
+                                                  &mPointSpriteIndexBuffer));
+        }
+
+        if (instancedPointSpritesActive)
+        {
+            // The index buffer is applied here because Instanced PointSprite emulation uses the a
+            // non-indexed rendering path in ANGLE (DrawArrays). This means that applyIndexBuffer()
+            // on the renderer will not be called and setting this buffer here ensures that the
+            // rendering path will contain the correct index buffers.
+            syncIndexBuffer(mPointSpriteIndexBuffer.get(), DXGI_FORMAT_R16_UINT, 0);
+        }
+    }
+
+    applyVertexBufferChanges();
     return gl::NoError();
 }
 
 gl::Error StateManager11::applyIndexBuffer(const gl::Context *context,
-                                           const void *indices,
-                                           GLsizei count,
-                                           GLenum type,
-                                           const gl::HasIndexRange &lazyIndexRange,
-                                           bool usePrimitiveRestartWorkaround)
+                                           const gl::DrawCallParams &params)
 {
     const auto &glState  = context->getGLState();
     gl::VertexArray *vao = glState.getVertexArray();
     VertexArray11 *vao11 = GetImplAs<VertexArray11>(vao);
 
-    GLenum destElementType =
-        GetIndexTranslationDestType(type, lazyIndexRange, usePrimitiveRestartWorkaround);
-
-    if (!vao11->updateElementArrayStorage(context, type, destElementType, indices) &&
-        !mIndexBufferIsDirty)
+    if (!mIndexBufferIsDirty)
     {
         // No streaming or index buffer application necessary.
         return gl::NoError();
     }
 
+    GLenum destElementType         = vao11->getCachedDestinationIndexType();
     gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
 
-    TranslatedIndexData *indexInfo = vao11->getCachedIndexInfo();
-    ANGLE_TRY(mIndexDataManager.prepareIndexData(context, type, destElementType, count,
-                                                 elementArrayBuffer, indices, indexInfo));
+    TranslatedIndexData indexInfo;
+    ANGLE_TRY(mIndexDataManager.prepareIndexData(context, params.type(), destElementType,
+                                                 params.indexCount(), elementArrayBuffer,
+                                                 params.indices(), &indexInfo));
 
     ID3D11Buffer *buffer = nullptr;
     DXGI_FORMAT bufferFormat =
-        (indexInfo->indexType == GL_UNSIGNED_INT) ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
-
-    if (indexInfo->storage)
+        (indexInfo.indexType == GL_UNSIGNED_INT) ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
+
+    if (indexInfo.storage)
     {
-        Buffer11 *storage = GetAs<Buffer11>(indexInfo->storage);
+        Buffer11 *storage = GetAs<Buffer11>(indexInfo.storage);
         ANGLE_TRY_RESULT(storage->getBuffer(context, BUFFER_USAGE_INDEX), buffer);
     }
     else
     {
-        IndexBuffer11 *indexBuffer = GetAs<IndexBuffer11>(indexInfo->indexBuffer);
+        IndexBuffer11 *indexBuffer = GetAs<IndexBuffer11>(indexInfo.indexBuffer);
         buffer                     = indexBuffer->getBuffer().get();
     }
 
     // Track dirty indices in the index range cache.
-    indexInfo->srcIndexData.srcIndicesChanged =
-        syncIndexBuffer(buffer, bufferFormat, indexInfo->startOffset);
+    indexInfo.srcIndexData.srcIndicesChanged =
+        syncIndexBuffer(buffer, bufferFormat, indexInfo.startOffset);
 
     mIndexBufferIsDirty = false;
 
-    vao11->setCachedIndexInfoValid();
+    vao11->updateCachedIndexInfo(indexInfo);
     return gl::NoError();
 }
 
 void StateManager11::setIndexBuffer(ID3D11Buffer *buffer,
                                     DXGI_FORMAT indexFormat,
                                     unsigned int offset)
 {
     if (syncIndexBuffer(buffer, indexFormat, offset))
     {
-        mIndexBufferIsDirty = true;
+        invalidateIndexBuffer();
     }
 }
 
 bool StateManager11::syncIndexBuffer(ID3D11Buffer *buffer,
                                      DXGI_FORMAT indexFormat,
                                      unsigned int offset)
 {
     if (buffer != mAppliedIB || indexFormat != mAppliedIBFormat || offset != mAppliedIBOffset)
@@ -2811,18 +2990,38 @@ bool StateManager11::syncIndexBuffer(ID3
 
     return false;
 }
 
 // Vertex buffer is invalidated outside this function.
 gl::Error StateManager11::updateVertexOffsetsForPointSpritesEmulation(GLint startVertex,
                                                                       GLsizei emulatedInstanceId)
 {
-    return mInputLayoutCache.updateVertexOffsetsForPointSpritesEmulation(
-        mRenderer, mCurrentAttributes, startVertex, emulatedInstanceId);
+    size_t reservedBuffers = GetReservedBufferCount(true);
+    for (size_t attribIndex = 0; attribIndex < mCurrentAttributes.size(); ++attribIndex)
+    {
+        const auto &attrib = *mCurrentAttributes[attribIndex];
+        size_t bufferIndex = reservedBuffers + attribIndex;
+
+        if (attrib.divisor > 0)
+        {
+            unsigned int offset = 0;
+            ANGLE_TRY_RESULT(attrib.computeOffset(startVertex), offset);
+            offset += (attrib.stride * (emulatedInstanceId / attrib.divisor));
+            if (offset != mCurrentVertexOffsets[bufferIndex])
+            {
+                invalidateInputLayout();
+                mDirtyVertexBufferRange.extend(static_cast<unsigned int>(bufferIndex));
+                mCurrentVertexOffsets[bufferIndex] = offset;
+            }
+        }
+    }
+
+    applyVertexBufferChanges();
+    return gl::NoError();
 }
 
 gl::Error StateManager11::generateSwizzle(const gl::Context *context, gl::Texture *texture)
 {
     if (!texture)
     {
         return gl::NoError();
     }
@@ -2847,17 +3046,17 @@ gl::Error StateManager11::generateSwizzl
 {
     const auto &glState    = context->getGLState();
     ProgramD3D *programD3D = GetImplAs<ProgramD3D>(glState.getProgram());
 
     unsigned int samplerRange = programD3D->getUsedSamplerRange(type);
 
     for (unsigned int i = 0; i < samplerRange; i++)
     {
-        GLenum textureType = programD3D->getSamplerTextureType(type, i);
+        gl::TextureType textureType = programD3D->getSamplerTextureType(type, i);
         GLint textureUnit  = programD3D->getSamplerMapping(type, i, context->getCaps());
         if (textureUnit != -1)
         {
             gl::Texture *texture = glState.getSamplerTexture(textureUnit, textureType);
             ASSERT(texture);
             if (texture->getTextureState().swizzleRequired())
             {
                 ANGLE_TRY(generateSwizzle(context, texture));
@@ -2865,18 +3064,18 @@ gl::Error StateManager11::generateSwizzl
         }
     }
 
     return gl::NoError();
 }
 
 gl::Error StateManager11::generateSwizzles(const gl::Context *context)
 {
-    ANGLE_TRY(generateSwizzlesForShader(context, gl::SHADER_VERTEX));
-    ANGLE_TRY(generateSwizzlesForShader(context, gl::SHADER_FRAGMENT));
+    ANGLE_TRY(generateSwizzlesForShader(context, gl::ShaderType::Vertex));
+    ANGLE_TRY(generateSwizzlesForShader(context, gl::ShaderType::Fragment));
     return gl::NoError();
 }
 
 gl::Error StateManager11::applyUniforms(ProgramD3D *programD3D)
 {
     UniformStorage11 *vertexUniformStorage =
         GetAs<UniformStorage11>(&programD3D->getVertexUniformStorage());
     UniformStorage11 *fragmentUniformStorage =
@@ -2886,22 +3085,24 @@ gl::Error StateManager11::applyUniforms(
 
     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
 
     const d3d11::Buffer *vertexConstantBuffer = nullptr;
     ANGLE_TRY(vertexUniformStorage->getConstantBuffer(mRenderer, &vertexConstantBuffer));
     const d3d11::Buffer *pixelConstantBuffer = nullptr;
     ANGLE_TRY(fragmentUniformStorage->getConstantBuffer(mRenderer, &pixelConstantBuffer));
 
-    if (vertexUniformStorage->size() > 0 && programD3D->areVertexUniformsDirty())
+    if (vertexUniformStorage->size() > 0 &&
+        programD3D->areShaderUniformsDirty(gl::ShaderType::Vertex))
     {
         UpdateUniformBuffer(deviceContext, vertexUniformStorage, vertexConstantBuffer);
     }
 
-    if (fragmentUniformStorage->size() > 0 && programD3D->areFragmentUniformsDirty())
+    if (fragmentUniformStorage->size() > 0 &&
+        programD3D->areShaderUniformsDirty(gl::ShaderType::Fragment))
     {
         UpdateUniformBuffer(deviceContext, fragmentUniformStorage, pixelConstantBuffer);
     }
 
     unsigned int slot = d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK;
 
     if (mCurrentConstantBufferVS[slot] != vertexConstantBuffer->getSerial())
     {
@@ -2925,45 +3126,45 @@ gl::Error StateManager11::applyUniforms(
 }
 
 gl::Error StateManager11::applyDriverUniforms(const ProgramD3D &programD3D)
 {
     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
 
     if (!mDriverConstantBufferVS.valid())
     {
-        size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::SHADER_VERTEX);
+        size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::ShaderType::Vertex);
 
         D3D11_BUFFER_DESC constantBufferDescription = {0};
         d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize);
         ANGLE_TRY(mRenderer->allocateResource(constantBufferDescription, &mDriverConstantBufferVS));
 
         ID3D11Buffer *driverVSConstants = mDriverConstantBufferVS.get();
         deviceContext->VSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
                                             &driverVSConstants);
     }
 
     if (!mDriverConstantBufferPS.valid())
     {
-        size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::SHADER_FRAGMENT);
+        size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::ShaderType::Fragment);
 
         D3D11_BUFFER_DESC constantBufferDescription = {0};
         d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize);
         ANGLE_TRY(mRenderer->allocateResource(constantBufferDescription, &mDriverConstantBufferPS));
 
         ID3D11Buffer *driverVSConstants = mDriverConstantBufferPS.get();
         deviceContext->PSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
                                             &driverVSConstants);
     }
 
     // Sampler metadata and driver constants need to coexist in the same constant buffer to conserve
     // constant buffer slots. We update both in the constant buffer if needed.
-    ANGLE_TRY(mShaderConstants.updateBuffer(mRenderer, gl::SHADER_VERTEX, programD3D,
+    ANGLE_TRY(mShaderConstants.updateBuffer(mRenderer, gl::ShaderType::Vertex, programD3D,
                                             mDriverConstantBufferVS));
-    ANGLE_TRY(mShaderConstants.updateBuffer(mRenderer, gl::SHADER_FRAGMENT, programD3D,
+    ANGLE_TRY(mShaderConstants.updateBuffer(mRenderer, gl::ShaderType::Fragment, programD3D,
                                             mDriverConstantBufferPS));
 
     // needed for the point sprite geometry shader
     // GSSetConstantBuffers triggers device removal on 9_3, so we should only call it for ES3.
     if (mRenderer->isES3Capable())
     {
         if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS.getSerial())
         {
@@ -2982,43 +3183,44 @@ gl::Error StateManager11::applyComputeUn
         GetAs<UniformStorage11>(&programD3D->getComputeUniformStorage());
     ASSERT(computeUniformStorage);
 
     const d3d11::Buffer *constantBuffer = nullptr;
     ANGLE_TRY(computeUniformStorage->getConstantBuffer(mRenderer, &constantBuffer));
 
     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
 
-    if (computeUniformStorage->size() > 0 && programD3D->areComputeUniformsDirty())
+    if (computeUniformStorage->size() > 0 &&
+        programD3D->areShaderUniformsDirty(gl::ShaderType::Compute))
     {
         UpdateUniformBuffer(deviceContext, computeUniformStorage, constantBuffer);
         programD3D->markUniformsClean();
     }
 
     if (mCurrentComputeConstantBuffer != constantBuffer->getSerial())
     {
         deviceContext->CSSetConstantBuffers(
             d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK, 1,
             constantBuffer->getPointer());
         mCurrentComputeConstantBuffer = constantBuffer->getSerial();
     }
 
     if (!mDriverConstantBufferCS.valid())
     {
-        size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::SHADER_COMPUTE);
+        size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::ShaderType::Compute);
 
         D3D11_BUFFER_DESC constantBufferDescription = {0};
         d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize);
         ANGLE_TRY(mRenderer->allocateResource(constantBufferDescription, &mDriverConstantBufferCS));
         ID3D11Buffer *buffer = mDriverConstantBufferCS.get();
         deviceContext->CSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
                                             &buffer);
     }
 
-    ANGLE_TRY(mShaderConstants.updateBuffer(mRenderer, gl::SHADER_COMPUTE, *programD3D,
+    ANGLE_TRY(mShaderConstants.updateBuffer(mRenderer, gl::ShaderType::Compute, *programD3D,
                                             mDriverConstantBufferCS));
 
     return gl::NoError();
 }
 
 gl::Error StateManager11::syncUniformBuffers(const gl::Context *context, ProgramD3D *programD3D)
 {
     unsigned int reservedVertex   = mRenderer->getReservedVertexUniformBuffers();
@@ -3027,17 +3229,17 @@ gl::Error StateManager11::syncUniformBuf
     programD3D->updateUniformBufferCache(context->getCaps(), reservedVertex, reservedFragment);
 
     const auto &vertexUniformBuffers     = programD3D->getVertexUniformBufferCache();
     const auto &fragmentUniformBuffers   = programD3D->getFragmentUniformBufferCache();
     const auto &glState                  = context->getGLState();
     ID3D11DeviceContext *deviceContext   = mRenderer->getDeviceContext();
     ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported();
 
-    mOnConstantBufferDirtyReceiver.reset();
+    mConstantBufferObserver.reset();
 
     for (size_t bufferIndex = 0; bufferIndex < vertexUniformBuffers.size(); bufferIndex++)
     {
         GLint binding = vertexUniformBuffers[bufferIndex];
 
         if (binding == -1)
         {
             continue;
@@ -3082,17 +3284,17 @@ gl::Error StateManager11::syncUniformBuf
         {
             deviceContext->VSSetConstantBuffers(appliedIndex, 1, constantBuffer->getPointer());
         }
 
         mCurrentConstantBufferVS[appliedIndex]       = constantBuffer->getSerial();
         mCurrentConstantBufferVSOffset[appliedIndex] = uniformBufferOffset;
         mCurrentConstantBufferVSSize[appliedIndex]   = uniformBufferSize;
 
-        mOnConstantBufferDirtyReceiver.bindVS(bufferIndex, bufferStorage);
+        mConstantBufferObserver.bindVS(bufferIndex, bufferStorage);
     }
 
     for (size_t bufferIndex = 0; bufferIndex < fragmentUniformBuffers.size(); bufferIndex++)
     {
         GLint binding = fragmentUniformBuffers[bufferIndex];
 
         if (binding == -1)
         {
@@ -3137,17 +3339,17 @@ gl::Error StateManager11::syncUniformBuf
         {
             deviceContext->PSSetConstantBuffers(appliedIndex, 1, constantBuffer->getPointer());
         }
 
         mCurrentConstantBufferPS[appliedIndex]       = constantBuffer->getSerial();
         mCurrentConstantBufferPSOffset[appliedIndex] = uniformBufferOffset;
         mCurrentConstantBufferPSSize[appliedIndex]   = uniformBufferSize;
 
-        mOnConstantBufferDirtyReceiver.bindPS(bufferIndex, bufferStorage);
+        mConstantBufferObserver.bindPS(bufferIndex, bufferStorage);
     }
 
     return gl::NoError();
 }
 
 gl::Error StateManager11::syncTransformFeedbackBuffers(const gl::Context *context)
 {
     const auto &glState = context->getGLState();
@@ -3179,129 +3381,140 @@ gl::Error StateManager11::syncTransformF
     deviceContext->SOSetTargets(tf11->getNumSOBuffers(), soBuffers->data(), soOffsets.data());
 
     mAppliedTFSerial = tf11->getSerial();
     tf11->onApply();
 
     return gl::NoError();
 }
 
-// DrawCallVertexParams implementation.
-DrawCallVertexParams::DrawCallVertexParams(GLint firstVertex,
-                                           GLsizei vertexCount,
-                                           GLsizei instances)
-    : mHasIndexRange(nullptr),
-      mFirstVertex(firstVertex),
-      mVertexCount(vertexCount),
-      mInstances(instances),
-      mBaseVertex(0)
-{
-}
-
-// Use when in a drawElements call.
-DrawCallVertexParams::DrawCallVertexParams(bool firstVertexDefinitelyZero,
-                                           const gl::HasIndexRange &hasIndexRange,
-                                           GLint baseVertex,
-                                           GLsizei instances)
-    : mHasIndexRange(&hasIndexRange),
-      mFirstVertex(),
-      mVertexCount(0),
-      mInstances(instances),
-      mBaseVertex(baseVertex)
-{
-    if (firstVertexDefinitelyZero)
-    {
-        mFirstVertex = baseVertex;
-    }
-}
-
-GLint DrawCallVertexParams::firstVertex() const
-{
-    if (!mFirstVertex.valid())
-    {
-        ensureResolved();
-        ASSERT(mFirstVertex.valid());
-    }
-    return mFirstVertex.value();
-}
-
-GLsizei DrawCallVertexParams::vertexCount() const
-{
-    ensureResolved();
-    return mVertexCount;
-}
-
-GLsizei DrawCallVertexParams::instances() const
-{
-    return mInstances;
-}
-
-void DrawCallVertexParams::ensureResolved() const
-{
-    if (mHasIndexRange)
-    {
-        ASSERT(!mFirstVertex.valid() || mFirstVertex == mBaseVertex);
-
-        // Resolve the index range now if we need to.
-        const auto &indexRange = mHasIndexRange->getIndexRange().value();
-        mFirstVertex           = mBaseVertex + static_cast<GLint>(indexRange.start);
-        mVertexCount           = static_cast<GLsizei>(indexRange.vertexCount());
-        mHasIndexRange         = nullptr;
-    }
-}
-
-// OnConstantBufferDirtyReceiver implementation.
-StateManager11::OnConstantBufferDirtyReceiver::OnConstantBufferDirtyReceiver()
+// ConstantBufferObserver implementation.
+StateManager11::ConstantBufferObserver::ConstantBufferObserver()
 {
     for (size_t vsIndex = 0; vsIndex < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS;
          ++vsIndex)
     {
         mBindingsVS.emplace_back(this, vsIndex);
     }
 
     for (size_t fsIndex = 0; fsIndex < gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS;
          ++fsIndex)
     {
         mBindingsPS.emplace_back(this, fsIndex);
     }
 }
 
-StateManager11::OnConstantBufferDirtyReceiver::~OnConstantBufferDirtyReceiver()
+StateManager11::ConstantBufferObserver::~ConstantBufferObserver()
 {
 }
 
-void StateManager11::OnConstantBufferDirtyReceiver::onSubjectStateChange(
-    const gl::Context *context,
-    angle::SubjectIndex index,
-    angle::SubjectMessage message)
+void StateManager11::ConstantBufferObserver::onSubjectStateChange(const gl::Context *context,
+                                                                  angle::SubjectIndex index,
+                                                                  angle::SubjectMessage message)
 {
-    StateManager11 *stateManager = GetImplAs<Context11>(context)->getRenderer()->getStateManager();
-    stateManager->invalidateProgramUniformBuffers();
+    if (message == angle::SubjectMessage::STORAGE_CHANGED)
+    {
+        StateManager11 *stateManager =
+            GetImplAs<Context11>(context)->getRenderer()->getStateManager();
+        stateManager->invalidateProgramUniformBuffers();
+    }
 }
 
-void StateManager11::OnConstantBufferDirtyReceiver::bindVS(size_t index, Buffer11 *buffer)
+void StateManager11::ConstantBufferObserver::bindVS(size_t index, Buffer11 *buffer)
 {
     ASSERT(buffer);
     ASSERT(index < mBindingsVS.size());
-    mBindingsVS[index].bind(buffer->getDirectSubject());
+    mBindingsVS[index].bind(buffer);
 }
 
-void StateManager11::OnConstantBufferDirtyReceiver::bindPS(size_t index, Buffer11 *buffer)
+void StateManager11::ConstantBufferObserver::bindPS(size_t index, Buffer11 *buffer)
 {
     ASSERT(buffer);
     ASSERT(index < mBindingsPS.size());
-    mBindingsPS[index].bind(buffer->getDirectSubject());
+    mBindingsPS[index].bind(buffer);
 }
 
-void StateManager11::OnConstantBufferDirtyReceiver::reset()
+void StateManager11::ConstantBufferObserver::reset()
 {
     for (angle::ObserverBinding &vsBinding : mBindingsVS)
     {
         vsBinding.bind(nullptr);
     }
 
     for (angle::ObserverBinding &psBinding : mBindingsPS)
     {
         psBinding.bind(nullptr);
     }
 }
 
+void StateManager11::syncPrimitiveTopology(const gl::State &glState,
+                                           ProgramD3D *programD3D,
+                                           GLenum currentDrawMode)
+{
+    D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
+
+    switch (currentDrawMode)
+    {
+        case GL_POINTS:
+        {
+            bool usesPointSize = programD3D->usesPointSize();
+
+            // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
+            // which affects varying interpolation. Since the value of gl_PointSize is
+            // undefined when not written, just skip drawing to avoid unexpected results.
+            if (!usesPointSize && !glState.isTransformFeedbackActiveUnpaused())
+            {
+                // Notify developers of risking undefined behavior.
+                WARN() << "Point rendering without writing to gl_PointSize.";
+                mCurrentMinimumDrawCount = std::numeric_limits<GLsizei>::max();
+                return;
+            }
+
+            // If instanced pointsprites are enabled and the shader uses gl_PointSize, the topology
+            // must be D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST.
+            if (usesPointSize && mRenderer->getWorkarounds().useInstancedPointSpriteEmulation)
+            {
+                primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
+            }
+            else
+            {
+                primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
+            }
+            mCurrentMinimumDrawCount = 1;
+            break;
+        }
+        case GL_LINES:
+            primitiveTopology        = D3D_PRIMITIVE_TOPOLOGY_LINELIST;
+            mCurrentMinimumDrawCount = 2;
+            break;
+        case GL_LINE_LOOP:
+            primitiveTopology        = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
+            mCurrentMinimumDrawCount = 2;
+            break;
+        case GL_LINE_STRIP:
+            primitiveTopology        = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
+            mCurrentMinimumDrawCount = 2;
+            break;
+        case GL_TRIANGLES:
+            primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
+            mCurrentMinimumDrawCount =
+                CullsEverything(glState) ? std::numeric_limits<GLsizei>::max() : 3;
+            break;
+        case GL_TRIANGLE_STRIP:
+            primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
+            mCurrentMinimumDrawCount =
+                CullsEverything(glState) ? std::numeric_limits<GLsizei>::max() : 3;
+            break;
+        // emulate fans via rewriting index buffer
+        case GL_TRIANGLE_FAN:
+            primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
+            mCurrentMinimumDrawCount =
+                CullsEverything(glState) ? std::numeric_limits<GLsizei>::max() : 3;
+            break;
+        default:
+            UNREACHABLE();
+            break;
+    }
+
+    setPrimitiveTopologyInternal(primitiveTopology);
+}
+
 }  // namespace rx
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
@@ -122,59 +122,28 @@ class ShaderConstants11 : angle::NonCopy
 
     static_assert(sizeof(SamplerMetadata) == 16u,
                   "Sampler metadata struct must be one 4-vec / 16 bytes.");
 
     // Return true if dirty.
     bool updateSamplerMetadata(SamplerMetadata *data, const gl::Texture &texture);
 
     Vertex mVertex;
-    bool mVertexDirty;
     Pixel mPixel;
-    bool mPixelDirty;
     Compute mCompute;
-    bool mComputeDirty;
+    gl::ShaderBitSet mShaderConstantsDirty;
 
     std::vector<SamplerMetadata> mSamplerMetadataVS;
     int mNumActiveVSSamplers;
     std::vector<SamplerMetadata> mSamplerMetadataPS;
     int mNumActivePSSamplers;
     std::vector<SamplerMetadata> mSamplerMetadataCS;
     int mNumActiveCSSamplers;
 };
 
-class DrawCallVertexParams final : angle::NonCopyable
-{
-  public:
-    // Use when in a drawArrays call.
-    DrawCallVertexParams(GLint firstVertex, GLsizei vertexCount, GLsizei instances);
-
-    // Use when in a drawElements call.
-    DrawCallVertexParams(bool firstVertexDefinitelyZero,
-                         const gl::HasIndexRange &hasIndexRange,
-                         GLint baseVertex,
-                         GLsizei instances);
-
-    // It should be possible to also use an overload to handle the 'slow' indirect draw path.
-    // TODO(jmadill): Indirect draw slow path overload.
-
-    GLint firstVertex() const;
-    GLsizei vertexCount() const;
-    GLsizei instances() const;
-
-  private:
-    void ensureResolved() const;
-
-    mutable const gl::HasIndexRange *mHasIndexRange;
-    mutable Optional<GLint> mFirstVertex;
-    mutable GLsizei mVertexCount;
-    GLsizei mInstances;
-    GLint mBaseVertex;
-};
-
 class StateManager11 final : angle::NonCopyable
 {
   public:
     StateManager11(Renderer11 *renderer);
     ~StateManager11();
 
     gl::Error initialize(const gl::Caps &caps, const gl::Extensions &extensions);
     void deinitialize();
@@ -207,42 +176,40 @@ class StateManager11 final : angle::NonC
     void invalidateViewport(const gl::Context *context);
 
     // Called by TextureStorage11::markLevelDirty.
     void invalidateSwizzles();
 
     // Called by the Framebuffer11 and VertexArray11.
     void invalidateShaders();
 
-    // Called by VertexArray11 to trigger attribute translation.
-    void invalidateVertexAttributeTranslation();
-
     // Called by the Program on Uniform Buffer change. Also called internally.
     void invalidateProgramUniformBuffers();
 
+    // Called by TransformFeedback11.
+    void invalidateTransformFeedback();
+
+    // Called by VertexArray11.
+    void invalidateInputLayout();
+
+    // Called by VertexArray11 element array buffer sync.
+    void invalidateIndexBuffer();
+
     void setRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv);
     void setRenderTargets(ID3D11RenderTargetView **rtvs, UINT numRtvs, ID3D11DepthStencilView *dsv);
 
     void onBeginQuery(Query11 *query);
     void onDeleteQueryObject(Query11 *query);
     gl::Error onMakeCurrent(const gl::Context *context);
 
     void setInputLayout(const d3d11::InputLayout *inputLayout);
 
-    // TODO(jmadill): Migrate to d3d11::Buffer.
-    bool queueVertexBufferChange(size_t bufferIndex,
-                                 ID3D11Buffer *buffer,
-                                 UINT stride,
-                                 UINT offset);
-    bool queueVertexOffsetChange(size_t bufferIndex, UINT offsetOnly);
-    void applyVertexBufferChanges();
-
     void setSingleVertexBuffer(const d3d11::Buffer *buffer, UINT stride, UINT offset);
 
-    gl::Error updateState(const gl::Context *context, GLenum drawMode);
+    gl::Error updateState(const gl::Context *context, const gl::DrawCallParams &drawCallParams);
 
     void setShaderResourceShared(gl::ShaderType shaderType,
                                  UINT resourceSlot,
                                  const d3d11::SharedSRV *srv);
     void setShaderResource(gl::ShaderType shaderType,
                            UINT resourceSlot,
                            const d3d11::ShaderResourceView *srv);
     void setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology);
@@ -261,40 +228,30 @@ class StateManager11 final : angle::NonC
     void setRasterizerState(const d3d11::RasterizerState *rasterizerState);
     void setSimpleViewport(const gl::Extents &viewportExtents);
     void setSimpleViewport(int width, int height);
     void setSimplePixelTextureAndSampler(const d3d11::SharedSRV &srv,
                                          const d3d11::SamplerState &samplerState);
     void setSimpleScissorRect(const gl::Rectangle &glRect);
     void setScissorRectD3D(const D3D11_RECT &d3dRect);
 
-    // Not handled by an internal dirty bit because of the extra draw parameters.
-    gl::Error applyVertexBuffer(const gl::Context *context,
-                                GLenum mode,
-                                const DrawCallVertexParams &vertexParams,
-                                bool isIndexedRendering);
-
-    gl::Error applyIndexBuffer(const gl::Context *context,
-                               const void *indices,
-                               GLsizei count,
-                               GLenum type,
-                               const gl::HasIndexRange &lazyIndexRange,
-                               bool usePrimitiveRestartWorkaround);
-
     void setIndexBuffer(ID3D11Buffer *buffer, DXGI_FORMAT indexFormat, unsigned int offset);
 
     gl::Error updateVertexOffsetsForPointSpritesEmulation(GLint startVertex,
                                                           GLsizei emulatedInstanceId);
 
     // TODO(jmadill): Should be private.
     gl::Error applyComputeUniforms(ProgramD3D *programD3D);
 
     // Only used in testing.
     InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; }
 
+    GLsizei getCurrentMinimumDrawCount() const { return mCurrentMinimumDrawCount; }
+    VertexDataManager *getVertexDataManager() { return &mVertexDataManager; }
+
   private:
     template <typename SRVType>
     void setShaderResourceInternal(gl::ShaderType shaderType,
                                    UINT resourceSlot,
                                    const SRVType *srv);
     template <typename UAVType>
     void setUnorderedAccessViewInternal(gl::ShaderType shaderType,
                                         UINT resourceSlot,
@@ -310,17 +267,18 @@ class StateManager11 final : angle::NonC
     gl::Error syncBlendState(const gl::Context *context,
                              const gl::Framebuffer *framebuffer,
                              const gl::BlendState &blendState,
                              const gl::ColorF &blendColor,
                              unsigned int sampleMask);
 
     gl::Error syncDepthStencilState(const gl::State &glState);
 
-    gl::Error syncRasterizerState(const gl::Context *context, bool pointDrawMode);
+    gl::Error syncRasterizerState(const gl::Context *context,
+                                  const gl::DrawCallParams &drawCallParams);
 
     void syncScissorRectangle(const gl::Rectangle &scissor, bool enabled);
 
     void syncViewport(const gl::Context *context);
 
     void checkPresentPath(const gl::Context *context);
 
     gl::Error syncFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer);
@@ -367,31 +325,55 @@ class StateManager11 final : angle::NonC
     void invalidateDriverUniforms();
     void invalidateProgramUniforms();
     void invalidateConstantBuffer(unsigned int slot);
 
     // Called by the Framebuffer11 directly.
     void processFramebufferInvalidation(const gl::Context *context);
 
     bool syncIndexBuffer(ID3D11Buffer *buffer, DXGI_FORMAT indexFormat, unsigned int offset);
+    gl::Error syncVertexBuffersAndInputLayout(const gl::Context *context,
+                                              const gl::DrawCallParams &vertexParams);
+
+    bool setInputLayoutInternal(const d3d11::InputLayout *inputLayout);
+
+    gl::Error applyVertexBuffers(const gl::Context *context,
+                                 const gl::DrawCallParams &drawCallParams);
+    // TODO(jmadill): Migrate to d3d11::Buffer.
+    bool queueVertexBufferChange(size_t bufferIndex,
+                                 ID3D11Buffer *buffer,
+                                 UINT stride,
+                                 UINT offset);
+    void applyVertexBufferChanges();
+    bool setPrimitiveTopologyInternal(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology);
+    void syncPrimitiveTopology(const gl::State &glState,
+                               ProgramD3D *programD3D,
+                               GLenum currentDrawMode);
+
+    // Not handled by an internal dirty bit because it isn't synced on drawArrays calls.
+    gl::Error applyIndexBuffer(const gl::Context *context,
+                               const gl::DrawCallParams &drawCallParams);
 
     enum DirtyBitType
     {
         DIRTY_BIT_RENDER_TARGET,
         DIRTY_BIT_VIEWPORT_STATE,
         DIRTY_BIT_SCISSOR_STATE,
         DIRTY_BIT_RASTERIZER_STATE,
         DIRTY_BIT_BLEND_STATE,
         DIRTY_BIT_DEPTH_STENCIL_STATE,
         DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE,
         DIRTY_BIT_PROGRAM_UNIFORMS,
         DIRTY_BIT_DRIVER_UNIFORMS,
         DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS,
         DIRTY_BIT_SHADERS,
         DIRTY_BIT_CURRENT_VALUE_ATTRIBS,
+        DIRTY_BIT_TRANSFORM_FEEDBACK,
+        DIRTY_BIT_VERTEX_BUFFERS_AND_INPUT_LAYOUT,
+        DIRTY_BIT_PRIMITIVE_TOPOLOGY,
         DIRTY_BIT_INVALID,
         DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
     };
 
     using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
 
     Renderer11 *mRenderer;
 
@@ -489,28 +471,28 @@ class StateManager11 final : angle::NonC
     std::vector<ID3D11UnorderedAccessView *> mNullUAVs;
 
     // Current translations of "Current-Value" data - owned by Context, not VertexArray.
     gl::AttributesMask mDirtyCurrentValueAttribs;
     std::vector<TranslatedAttribute> mCurrentValueAttribs;
 
     // Current applied input layout.
     ResourceSerial mCurrentInputLayout;
-    bool mInputLayoutIsDirty;
-    bool mVertexAttribsNeedTranslation;
 
     // Current applied vertex states.
     // TODO(jmadill): Figure out how to use ResourceSerial here.
     gl::AttribArray<ID3D11Buffer *> mCurrentVertexBuffers;
     gl::AttribArray<UINT> mCurrentVertexStrides;
     gl::AttribArray<UINT> mCurrentVertexOffsets;
     gl::RangeUI mDirtyVertexBufferRange;
 
     // Currently applied primitive topology
     D3D11_PRIMITIVE_TOPOLOGY mCurrentPrimitiveTopology;
+    GLenum mLastAppliedDrawMode;
+    GLsizei mCurrentMinimumDrawCount;
 
     // Currently applied shaders
     ResourceSerial mAppliedVertexShader;
     ResourceSerial mAppliedGeometryShader;
     ResourceSerial mAppliedPixelShader;
     ResourceSerial mAppliedComputeShader;
 
     // Currently applied sampler states
@@ -545,54 +527,55 @@ class StateManager11 final : angle::NonC
     // Driver Constants.
     d3d11::Buffer mDriverConstantBufferVS;
     d3d11::Buffer mDriverConstantBufferPS;
     d3d11::Buffer mDriverConstantBufferCS;
 
     ResourceSerial mCurrentComputeConstantBuffer;
     ResourceSerial mCurrentGeometryConstantBuffer;
 
+    d3d11::Buffer mPointSpriteVertexBuffer;
+    d3d11::Buffer mPointSpriteIndexBuffer;
+
     template <typename T>
     using VertexConstantBufferArray =
         std::array<T, gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS>;
 
     VertexConstantBufferArray<ResourceSerial> mCurrentConstantBufferVS;
     VertexConstantBufferArray<GLintptr> mCurrentConstantBufferVSOffset;
     VertexConstantBufferArray<GLsizeiptr> mCurrentConstantBufferVSSize;
 
     template <typename T>
     using FragmentConstantBufferArray =
         std::array<T, gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS>;
 
     FragmentConstantBufferArray<ResourceSerial> mCurrentConstantBufferPS;
     FragmentConstantBufferArray<GLintptr> mCurrentConstantBufferPSOffset;
     FragmentConstantBufferArray<GLsizeiptr> mCurrentConstantBufferPSSize;
 
-    class OnConstantBufferDirtyReceiver : public angle::ObserverInterface
+    class ConstantBufferObserver : public angle::ObserverInterface
     {
       public:
-        OnConstantBufferDirtyReceiver();
-        ~OnConstantBufferDirtyReceiver() override;
+        ConstantBufferObserver();
+        ~ConstantBufferObserver() override;
 
         void onSubjectStateChange(const gl::Context *context,
                                   angle::SubjectIndex index,
                                   angle::SubjectMessage message) override;
 
         void reset();
         void bindVS(size_t index, Buffer11 *buffer);
         void bindPS(size_t index, Buffer11 *buffer);
 
       private:
         std::vector<angle::ObserverBinding> mBindingsVS;
         std::vector<angle::ObserverBinding> mBindingsPS;
     };
-    OnConstantBufferDirtyReceiver mOnConstantBufferDirtyReceiver;
+    ConstantBufferObserver mConstantBufferObserver;
 
     // Currently applied transform feedback buffers
     Serial mAppliedTFSerial;
 
     Serial mEmptySerial;
-
-    bool mIsTransformFeedbackCurrentlyActiveUnpaused;
 };
 
 }  // namespace rx
 #endif  // LIBANGLE_RENDERER_D3D11_STATEMANAGER11_H_
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
@@ -25,50 +25,16 @@
 #include "libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h"
 #include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
 
 namespace rx
 {
-
-namespace
-{
-
-void InvalidateRenderTarget(const gl::Context *context, RenderTarget11 *renderTarget)
-{
-    if (renderTarget)
-    {
-        renderTarget->signalDirty(context);
-    }
-}
-
-RenderTarget11 *GetRenderTarget(std::unique_ptr<RenderTarget11> *pointer)
-{
-    return pointer->get();
-}
-
-template <typename KeyT>
-RenderTarget11 *GetRenderTarget(std::pair<KeyT, std::unique_ptr<RenderTarget11>> *pair)
-{
-    return pair->second.get();
-}
-
-template <typename T>
-void InvalidateRenderTargetContainer(const gl::Context *context, T *renderTargetContainer)
-{
-    for (auto &rt : *renderTargetContainer)
-    {
-        InvalidateRenderTarget(context, GetRenderTarget(&rt));
-    }
-}
-
-}  // anonymous namespace
-
 TextureStorage11::SamplerKey::SamplerKey()
     : baseLevel(0), mipLevels(0), swizzle(false), dropStencil(false)
 {
 }
 
 TextureStorage11::SamplerKey::SamplerKey(int baseLevel,
                                          int mipLevels,
                                          bool swizzle,
@@ -747,19 +713,17 @@ gl::Error TextureStorage11::setData(cons
 
     const TextureHelper11 *resource = nullptr;
     ANGLE_TRY(getResource(context, &resource));
     ASSERT(resource && resource->valid());
 
     UINT destSubresource = getSubresourceIndex(index);
 
     const gl::InternalFormat &internalFormatInfo =
-        gl::GetSizedInternalFormatInfo(image->getInternalFormat());
-    const gl::InternalFormat &packInfo =
-        gl::GetPackFormatInfo(image->getInternalFormat(), type);
+        gl::GetInternalFormatInfo(image->getInternalFormat(), type);
 
     gl::Box levelBox(0, 0, 0, getLevelWidth(index.mipIndex), getLevelHeight(index.mipIndex),
                      getLevelDepth(index.mipIndex));
     bool fullUpdate = (destBox == nullptr || *destBox == levelBox);
     ASSERT(internalFormatInfo.depthBits == 0 || fullUpdate);
 
     // TODO(jmadill): Handle compressed formats
     // Compressed formats have different load syntax, so we'll have to handle them with slightly
@@ -767,24 +731,24 @@ gl::Error TextureStorage11::setData(cons
     // with compressed formats in the calling logic.
     ASSERT(!internalFormatInfo.compressed);
 
     const int width    = destBox ? destBox->width : static_cast<int>(image->getWidth());
     const int height   = destBox ? destBox->height : static_cast<int>(image->getHeight());
     const int depth    = destBox ? destBox->depth : static_cast<int>(image->getDepth());
     GLuint srcRowPitch = 0;
     ANGLE_TRY_RESULT(
-        packInfo.computeRowPitch(width, unpack.alignment, unpack.rowLength),
+        internalFormatInfo.computeRowPitch(type, width, unpack.alignment, unpack.rowLength),
         srcRowPitch);
     GLuint srcDepthPitch = 0;
-    ANGLE_TRY_RESULT(packInfo.computeDepthPitch(height, unpack.imageHeight, srcRowPitch),
+    ANGLE_TRY_RESULT(internalFormatInfo.computeDepthPitch(height, unpack.imageHeight, srcRowPitch),
                      srcDepthPitch);
     GLuint srcSkipBytes = 0;
     ANGLE_TRY_RESULT(
-        packInfo.computeSkipBytes(srcRowPitch, srcDepthPitch, unpack, index.is3D()),
+        internalFormatInfo.computeSkipBytes(type, srcRowPitch, srcDepthPitch, unpack, index.is3D()),
         srcSkipBytes);
 
     const d3d11::Format &d3d11Format =
         d3d11::Format::Get(image->getInternalFormat(), mRenderer->getRenderer11DeviceCaps());
     const d3d11::DXGIFormatSize &dxgiFormatInfo =
         d3d11::GetDXGIFormatSizeInfo(d3d11Format.texFormat);
 
     const size_t outputPixelSize = dxgiFormatInfo.pixelBytes;
@@ -925,20 +889,16 @@ gl::Error TextureStorage11_2D::onDestroy
 
     if (mHasKeyedMutex)
     {
         // If the keyed mutex is released that will unbind it and cause the state cache to become
         // desynchronized.
         mRenderer->getStateManager()->invalidateBoundViews();
     }
 
-    // Invalidate RenderTargets.
-    InvalidateRenderTargetContainer(context, &mRenderTarget);
-    InvalidateRenderTarget(context, mLevelZeroRenderTarget.get());
-
     return gl::NoError();
 }
 
 TextureStorage11_2D::~TextureStorage11_2D()
 {
 }
 
 gl::Error TextureStorage11_2D::copyToStorage(const gl::Context *context,
@@ -1021,28 +981,18 @@ gl::Error TextureStorage11_2D::useLevelZ
                                                  mLevelZeroTexture.get(), 0, nullptr);
         }
 
         mUseLevelZeroTexture = false;
     }
 
     if (lastSetting != mUseLevelZeroTexture)
     {
-        // Mark everything as dirty to be conservative.
-        if (mLevelZeroRenderTarget)
-        {
-            mLevelZeroRenderTarget->signalDirty(context);
-        }
-        for (auto &renderTarget : mRenderTarget)
-        {
-            if (renderTarget)
-            {
-                renderTarget->signalDirty(context);
-            }
-        }
+        ASSERT(mSubject);
+        mSubject->onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
     }
 
     return gl::NoError();
 }
 
 void TextureStorage11_2D::associateImage(Image11 *image, const gl::ImageIndex &index)
 {
     const GLint level = index.mipIndex;
@@ -1154,17 +1104,25 @@ gl::Error TextureStorage11_2D::ensureTex
         desc.SampleDesc.Count   = 1;
         desc.SampleDesc.Quality = 0;
         desc.Usage              = D3D11_USAGE_DEFAULT;
         desc.BindFlags          = getBindFlags();
         desc.CPUAccessFlags     = 0;
         desc.MiscFlags          = getMiscFlags();
 
         ANGLE_TRY(mRenderer->allocateTexture(desc, mFormatInfo, outputTexture));
-        outputTexture->setDebugName("TexStorage2D.Texture");
+
+        if (useLevelZeroTexture)
+        {
+            outputTexture->setDebugName("TexStorage2D.Level0Texture");
+        }
+        else
+        {
+            outputTexture->setDebugName("TexStorage2D.Texture");
+        }
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureStorage11_2D::getRenderTarget(const gl::Context *context,
                                                const gl::ImageIndex &index,
                                                RenderTargetD3D **outRT)
@@ -1211,16 +1169,17 @@ gl::Error TextureStorage11_2D::getRender
         {
             D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
             rtvDesc.Format             = mFormatInfo.rtvFormat;
             rtvDesc.ViewDimension      = D3D11_RTV_DIMENSION_TEXTURE2D;
             rtvDesc.Texture2D.MipSlice = mTopLevel + level;
 
             d3d11::RenderTargetView rtv;
             ANGLE_TRY(mRenderer->allocateResource(rtvDesc, mLevelZeroTexture.get(), &rtv));
+            rtv.setDebugName("TexStorage2D.Level0RTV");
 
             mLevelZeroRenderTarget.reset(new TextureRenderTarget11(
                 std::move(rtv), mLevelZeroTexture, d3d11::SharedSRV(), d3d11::SharedSRV(),
                 mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level),
                 getLevelHeight(level), 1, 0));
         }
 
         *outRT = mLevelZeroRenderTarget.get();
@@ -1231,16 +1190,17 @@ gl::Error TextureStorage11_2D::getRender
     {
         D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
         rtvDesc.Format             = mFormatInfo.rtvFormat;
         rtvDesc.ViewDimension      = D3D11_RTV_DIMENSION_TEXTURE2D;
         rtvDesc.Texture2D.MipSlice = mTopLevel + level;
 
         d3d11::RenderTargetView rtv;
         ANGLE_TRY(mRenderer->allocateResource(rtvDesc, texture->get(), &rtv));
+        rtv.setDebugName("TexStorage2D.RTV");
 
         mRenderTarget[level].reset(new TextureRenderTarget11(
             std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(),
             getLevelWidth(level), getLevelHeight(level), 1, 0));
 
         *outRT = mRenderTarget[level].get();
         return gl::NoError();
     }
@@ -1250,16 +1210,17 @@ gl::Error TextureStorage11_2D::getRender
     D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
     dsvDesc.Format             = mFormatInfo.dsvFormat;
     dsvDesc.ViewDimension      = D3D11_DSV_DIMENSION_TEXTURE2D;
     dsvDesc.Texture2D.MipSlice = mTopLevel + level;
     dsvDesc.Flags              = 0;
 
     d3d11::DepthStencilView dsv;
     ANGLE_TRY(mRenderer->allocateResource(dsvDesc, texture->get(), &dsv));
+    dsv.setDebugName("TexStorage2D.DSV");
 
     mRenderTarget[level].reset(new TextureRenderTarget11(
         std::move(dsv), *texture, *srv, mFormatInfo.internalFormat, getFormatSet(),
         getLevelWidth(level), getLevelHeight(level), 1, 0));
 
     *outRT = mRenderTarget[level].get();
     return gl::NoError();
 }
@@ -1889,22 +1850,16 @@ gl::Error TextureStorage11_Cube::onDestr
 
                 // We must let the Images recover their data before we delete it from the
                 // TextureStorage.
                 ANGLE_TRY(mAssociatedImages[face][level]->recoverFromAssociatedStorage(context));
             }
         }
     }
 
-    for (auto &faceRenderTargets : mRenderTarget)
-    {
-        InvalidateRenderTargetContainer(context, &faceRenderTargets);
-    }
-    InvalidateRenderTargetContainer(context, &mLevelZeroRenderTarget);
-
     return gl::NoError();
 }
 
 TextureStorage11_Cube::~TextureStorage11_Cube()
 {
 }
 
 UINT TextureStorage11_Cube::getSubresourceIndex(const gl::ImageIndex &index) const
@@ -2539,19 +2494,16 @@ gl::Error TextureStorage11_3D::onDestroy
             mAssociatedImages[i]->verifyAssociatedStorageValid(this);
 
             // We must let the Images recover their data before we delete it from the
             // TextureStorage.
             ANGLE_TRY(mAssociatedImages[i]->recoverFromAssociatedStorage(context));
         }
     }
 
-    InvalidateRenderTargetContainer(context, &mLevelRenderTargets);
-    InvalidateRenderTargetContainer(context, &mLevelLayerRenderTargets);
-
     return gl::NoError();
 }
 
 TextureStorage11_3D::~TextureStorage11_3D()
 {
 }
 
 void TextureStorage11_3D::associateImage(Image11 *image, const gl::ImageIndex &index)
@@ -2865,18 +2817,16 @@ gl::Error TextureStorage11_2DArray::onDe
 
             // We must let the Images recover their data before we delete it from the
             // TextureStorage.
             ANGLE_TRY(iter.second->recoverFromAssociatedStorage(context));
         }
     }
     mAssociatedImages.clear();
 
-    InvalidateRenderTargetContainer(context, &mRenderTargets);
-
     return gl::NoError();
 }
 
 TextureStorage11_2DArray::~TextureStorage11_2DArray()
 {
 }
 
 void TextureStorage11_2DArray::associateImage(Image11 *image, const gl::ImageIndex &index)
@@ -3246,17 +3196,16 @@ TextureStorage11_2DMultisample::TextureS
     mTextureHeight        = height;
     mTextureDepth         = 1;
     mSamples              = samples;
     mFixedSampleLocations = fixedSampleLocations;
 }
 
 gl::Error TextureStorage11_2DMultisample::onDestroy(const gl::Context *context)
 {
-    InvalidateRenderTarget(context, mRenderTarget.get());
     mRenderTarget.reset();
     return gl::NoError();
 }
 
 TextureStorage11_2DMultisample::~TextureStorage11_2DMultisample()
 {
 }
 
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp
@@ -41,43 +41,49 @@ void TransformFeedback11::begin(GLenum p
         {
             mBufferOffsets[bindingIdx] = static_cast<UINT>(binding.getOffset());
         }
         else
         {
             mBufferOffsets[bindingIdx] = 0;
         }
     }
+    mRenderer->getStateManager()->invalidateTransformFeedback();
 }
 
 void TransformFeedback11::end()
 {
+    mRenderer->getStateManager()->invalidateTransformFeedback();
     if (mRenderer->getWorkarounds().flushAfterEndingTransformFeedback)
     {
         mRenderer->getDeviceContext()->Flush();
     }
 }
 
 void TransformFeedback11::pause()
 {
+    mRenderer->getStateManager()->invalidateTransformFeedback();
 }
 
 void TransformFeedback11::resume()
 {
+    mRenderer->getStateManager()->invalidateTransformFeedback();
 }
 
 void TransformFeedback11::bindGenericBuffer(const gl::BindingPointer<gl::Buffer> &binding)
 {
+    mRenderer->getStateManager()->invalidateTransformFeedback();
 }
 
 void TransformFeedback11::bindIndexedBuffer(size_t index,
                                             const gl::OffsetBindingPointer<gl::Buffer> &binding)
 {
     mIsDirty              = true;
     mBufferOffsets[index] = static_cast<UINT>(binding.getOffset());
+    mRenderer->getStateManager()->invalidateTransformFeedback();
 }
 
 void TransformFeedback11::onApply()
 {
     mIsDirty = false;
 
     // Change all buffer offsets to -1 so that if any of them need to be re-applied, the are set to
     // append
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp
@@ -6,409 +6,333 @@
 // VertexArray11:
 //   Implementation of rx::VertexArray11.
 //
 
 #include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
 
 #include "common/bitset_utils.h"
 #include "libANGLE/Context.h"
+#include "libANGLE/renderer/d3d/IndexBuffer.h"
 #include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
 
 using namespace angle;
 
 namespace rx
 {
-
-namespace
-{
-angle::Subject *GetBufferSubject(Buffer11 *buffer11, IndexStorageType storageType)
-{
-    switch (storageType)
-    {
-        case IndexStorageType::Direct:
-            return buffer11->getDirectSubject();
-        case IndexStorageType::Static:
-            return buffer11->getStaticSubject();
-        case IndexStorageType::Dynamic:
-            return buffer11 ? buffer11->getStaticSubject() : nullptr;
-        default:
-            UNREACHABLE();
-            return nullptr;
-    }
-}
-}  // anonymous namespace
-
 VertexArray11::VertexArray11(const gl::VertexArrayState &data)
     : VertexArrayImpl(data),
       mAttributeStorageTypes(data.getMaxAttribs(), VertexStorageType::CURRENT_VALUE),
       mTranslatedAttribs(data.getMaxAttribs()),
-      mCurrentArrayBuffers(data.getMaxAttribs()),
-      mCurrentElementArrayBuffer(),
-      mOnArrayBufferDataDirty(),
-      mOnElementArrayBufferDataDirty(this, mCurrentArrayBuffers.size()),
       mAppliedNumViewsToDivisor(1),
-      mLastElementType(GL_NONE),
-      mLastDrawElementsOffset(0),
       mCurrentElementArrayStorage(IndexStorageType::Invalid),
-      mCachedIndexInfoValid(false)
+      mCachedDestinationIndexType(GL_NONE)
 {
-    for (size_t attribIndex = 0; attribIndex < mCurrentArrayBuffers.size(); ++attribIndex)
-    {
-        mOnArrayBufferDataDirty.emplace_back(this, attribIndex);
-    }
 }
 
 VertexArray11::~VertexArray11()
 {
 }
 
 void VertexArray11::destroy(const gl::Context *context)
 {
-    for (auto &buffer : mCurrentArrayBuffers)
-    {
-        if (buffer.get())
-        {
-            buffer.set(context, nullptr);
-        }
-    }
-
-    mCurrentElementArrayBuffer.set(context, nullptr);
 }
 
-void VertexArray11::syncState(const gl::Context *context,
-                              const gl::VertexArray::DirtyBits &dirtyBits)
+gl::Error VertexArray11::syncState(const gl::Context *context,
+                                   const gl::VertexArray::DirtyBits &dirtyBits,
+                                   const gl::VertexArray::DirtyAttribBitsArray &attribBits,
+                                   const gl::VertexArray::DirtyBindingBitsArray &bindingBits)
 {
     ASSERT(dirtyBits.any());
 
+    Renderer11 *renderer         = GetImplAs<Context11>(context)->getRenderer();
+    StateManager11 *stateManager = renderer->getStateManager();
+
     // Generate a state serial. This serial is used in the program class to validate the cached
     // input layout, and skip recomputation in the fast path.
-    Renderer11 *renderer = GetImplAs<Context11>(context)->getRenderer();
     mCurrentStateSerial = renderer->generateSerial();
 
-    // TODO(jmadill): Individual attribute invalidation.
-    renderer->getStateManager()->invalidateVertexBuffer();
+    bool invalidateVertexBuffer = false;
 
-    for (auto dirtyBit : dirtyBits)
+    // Make sure we trigger re-translation for static index or vertex data.
+    for (size_t dirtyBit : dirtyBits)
     {
-        if (dirtyBit == gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER)
-        {
-            mCachedIndexInfoValid = false;
-            mLastElementType      = GL_NONE;
-        }
-        else
+        switch (dirtyBit)
         {
-            size_t index = gl::VertexArray::GetVertexIndexFromDirtyBit(dirtyBit);
-            // TODO(jiawei.shao@intel.com): Vertex Attrib Bindings
-            ASSERT(index == mState.getBindingIndexFromAttribIndex(index));
-            mAttribsToUpdate.set(index);
-        }
-    }
-}
+            case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER:
+            case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA:
+            {
+                mLastDrawElementsType.reset();
+                mLastDrawElementsIndices.reset();
+                mLastPrimitiveRestartEnabled.reset();
+                mCachedIndexInfo.reset();
+                break;
+            }
 
-bool VertexArray11::flushAttribUpdates(const gl::Context *context)
-{
-    if (mAttribsToUpdate.any())
-    {
-        const auto &activeLocations =
-            context->getGLState().getProgram()->getActiveAttribLocationsMask();
+            default:
+            {
+                size_t index = gl::VertexArray::GetVertexIndexFromDirtyBit(dirtyBit);
 
-        // Skip attrib locations the program doesn't use.
-        gl::AttributesMask activeToUpdate = mAttribsToUpdate & activeLocations;
-
-        for (auto toUpdateIndex : activeToUpdate)
-        {
-            mAttribsToUpdate.reset(toUpdateIndex);
-            updateVertexAttribStorage(context, toUpdateIndex);
-        }
-
-        return true;
-    }
+                // TODO(jiawei.shao@intel.com): Vertex Attrib Bindings
+                ASSERT(index == mState.getBindingIndexFromAttribIndex(index));
 
-    return false;
-}
-
-bool VertexArray11::updateElementArrayStorage(const gl::Context *context,
-                                              GLenum elementType,
-                                              GLenum destElementType,
-                                              const void *indices)
-{
-    unsigned int offset = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(indices));
-
-    if (mCachedIndexInfoValid && mLastElementType == elementType &&
-        offset == mLastDrawElementsOffset)
-    {
-        // Dynamic index buffers must be re-streamed every draw.
-        return (mCurrentElementArrayStorage == IndexStorageType::Dynamic);
+                if (dirtyBit < gl::VertexArray::DIRTY_BIT_BINDING_MAX)
+                {
+                    updateVertexAttribStorage(stateManager, dirtyBit, index);
+                }
+                else
+                {
+                    ASSERT(dirtyBit >= gl::VertexArray::DIRTY_BIT_BUFFER_DATA_0 &&
+                           dirtyBit < gl::VertexArray::DIRTY_BIT_BUFFER_DATA_MAX);
+                    if (mAttributeStorageTypes[index] == VertexStorageType::STATIC)
+                    {
+                        mAttribsToTranslate.set(index);
+                    }
+                }
+                invalidateVertexBuffer = true;
+                break;
+            }
+        }
     }
 
-    gl::Buffer *newBuffer           = mState.getElementArrayBuffer().get();
-    gl::Buffer *oldBuffer           = mCurrentElementArrayBuffer.get();
-    bool needsTranslation           = false;
-    IndexStorageType newStorageType = ClassifyIndexStorage(
-        context->getGLState(), newBuffer, elementType, destElementType, offset, &needsTranslation);
-
-    if (newBuffer != oldBuffer)
-    {
-        mCurrentElementArrayBuffer.set(context, newBuffer);
-    }
-
-    if (newStorageType != mCurrentElementArrayStorage || newBuffer != oldBuffer)
+    if (invalidateVertexBuffer)
     {
-        Buffer11 *newBuffer11 = SafeGetImplAs<Buffer11>(newBuffer);
-
-        angle::Subject *subject = GetBufferSubject(newBuffer11, newStorageType);
-
-        mCurrentElementArrayStorage = newStorageType;
-        mOnElementArrayBufferDataDirty.bind(subject);
-        needsTranslation = true;
-    }
-
-    if (mLastDrawElementsOffset != offset)
-    {
-        needsTranslation        = true;
-        mLastDrawElementsOffset = offset;
-    }
-
-    if (mLastElementType != elementType)
-    {
-        needsTranslation = true;
-        mLastElementType = elementType;
+        // TODO(jmadill): Individual attribute invalidation.
+        stateManager->invalidateVertexBuffer();
     }
 
-    // TODO(jmadill): We should probably promote static usage immediately, because this can change
-    // the storage type for dynamic buffers.
-    return needsTranslation || !mCachedIndexInfoValid;
+    return gl::NoError();
 }
 
-void VertexArray11::updateVertexAttribStorage(const gl::Context *context, size_t attribIndex)
+gl::Error VertexArray11::syncStateForDraw(const gl::Context *context,
+                                          const gl::DrawCallParams &drawCallParams)
 {
-    const auto &attrib  = mState.getVertexAttribute(attribIndex);
-    const auto &binding = mState.getBindingFromAttribIndex(attribIndex);
+    Renderer11 *renderer         = GetImplAs<Context11>(context)->getRenderer();
+    StateManager11 *stateManager = renderer->getStateManager();
 
-    // Note: having an unchanged storage type doesn't mean the attribute is clean.
-    auto oldStorageType = mAttributeStorageTypes[attribIndex];
-    auto newStorageType = ClassifyAttributeStorage(attrib, binding);
+    const gl::State &glState   = context->getGLState();
+    const gl::Program *program = glState.getProgram();
+    ASSERT(program);
+    mAppliedNumViewsToDivisor = (program->usesMultiview() ? program->getNumViews() : 1);
 
-    mAttributeStorageTypes[attribIndex] = newStorageType;
-
-    StateManager11 *stateManager = GetImplAs<Context11>(context)->getRenderer()->getStateManager();
-
-    if (newStorageType == VertexStorageType::DYNAMIC)
+    if (mAttribsToTranslate.any())
     {
-        if (oldStorageType != VertexStorageType::DYNAMIC)
+        const gl::AttributesMask &activeLocations =
+            glState.getProgram()->getActiveAttribLocationsMask();
+        gl::AttributesMask activeDirtyAttribs = (mAttribsToTranslate & activeLocations);
+        if (activeDirtyAttribs.any())
         {
-            // Sync dynamic attribs in a different set.
-            mAttribsToTranslate.reset(attribIndex);
-            mDynamicAttribsMask.set(attribIndex);
-        }
-    }
-    else
-    {
-        mAttribsToTranslate.set(attribIndex);
-        stateManager->invalidateVertexAttributeTranslation();
-
-        if (oldStorageType == VertexStorageType::DYNAMIC)
-        {
-            ASSERT(mDynamicAttribsMask[attribIndex]);
-            mDynamicAttribsMask.reset(attribIndex);
+            ANGLE_TRY(updateDirtyAttribs(context, activeDirtyAttribs));
+            stateManager->invalidateInputLayout();
         }
     }
 
-    gl::Buffer *oldBufferGL = mCurrentArrayBuffers[attribIndex].get();
-    gl::Buffer *newBufferGL = binding.getBuffer().get();
-    Buffer11 *oldBuffer11   = oldBufferGL ? GetImplAs<Buffer11>(oldBufferGL) : nullptr;
-    Buffer11 *newBuffer11   = newBufferGL ? GetImplAs<Buffer11>(newBufferGL) : nullptr;
-
-    if (oldBuffer11 != newBuffer11 || oldStorageType != newStorageType)
+    if (mDynamicAttribsMask.any())
     {
-        angle::Subject *subject = nullptr;
+        const gl::AttributesMask &activeLocations =
+            glState.getProgram()->getActiveAttribLocationsMask();
+        gl::AttributesMask activeDynamicAttribs = (mDynamicAttribsMask & activeLocations);
 
-        if (newStorageType == VertexStorageType::CURRENT_VALUE)
+        if (activeDynamicAttribs.any())
         {
-            stateManager->invalidateCurrentValueAttrib(attribIndex);
+            ANGLE_TRY(updateDynamicAttribs(context, stateManager->getVertexDataManager(),
+                                           drawCallParams, activeDynamicAttribs));
+            stateManager->invalidateInputLayout();
         }
-        else if (newBuffer11 != nullptr)
+    }
+
+    if (drawCallParams.isDrawElements())
+    {
+        bool restartEnabled = context->getGLState().isPrimitiveRestartEnabled();
+        if (!mLastDrawElementsType.valid() ||
+            mLastDrawElementsType.value() != drawCallParams.type() ||
+            mLastDrawElementsIndices.value() != drawCallParams.indices() ||
+            mLastPrimitiveRestartEnabled.value() != restartEnabled)
+        {
+            mLastDrawElementsType        = drawCallParams.type();
+            mLastDrawElementsIndices     = drawCallParams.indices();
+            mLastPrimitiveRestartEnabled = restartEnabled;
+
+            ANGLE_TRY(updateElementArrayStorage(context, drawCallParams, restartEnabled));
+            stateManager->invalidateIndexBuffer();
+        }
+        else if (mCurrentElementArrayStorage == IndexStorageType::Dynamic)
         {
-            // Note that for static callbacks, promotion to a static buffer from a dynamic buffer
-            // means we need to tag dynamic buffers with static callbacks.
-            switch (newStorageType)
-            {
-                case VertexStorageType::DIRECT:
-                    subject = newBuffer11->getDirectSubject();
-                    break;
-                case VertexStorageType::STATIC:
-                case VertexStorageType::DYNAMIC:
-                    subject = newBuffer11->getStaticSubject();
-                    break;
-                default:
-                    UNREACHABLE();
-                    break;
-            }
+            stateManager->invalidateIndexBuffer();
         }
+    }
 
-        mOnArrayBufferDataDirty[attribIndex].bind(subject);
-        mCurrentArrayBuffers[attribIndex].set(context, binding.getBuffer().get());
+    return gl::NoError();
+}
+
+gl::Error VertexArray11::updateElementArrayStorage(const gl::Context *context,
+                                                   const gl::DrawCallParams &drawCallParams,
+                                                   bool restartEnabled)
+{
+    bool usePrimitiveRestartWorkaround =
+        UsePrimitiveRestartWorkaround(restartEnabled, drawCallParams.type());
+
+    ANGLE_TRY(GetIndexTranslationDestType(context, drawCallParams, usePrimitiveRestartWorkaround,
+                                          &mCachedDestinationIndexType));
+
+    unsigned int offset =
+        static_cast<unsigned int>(reinterpret_cast<uintptr_t>(drawCallParams.indices()));
+
+    mCurrentElementArrayStorage =
+        ClassifyIndexStorage(context->getGLState(), mState.getElementArrayBuffer().get(),
+                             drawCallParams.type(), mCachedDestinationIndexType, offset);
+
+    // Mark non-static buffers as irrelevant.
+    bool isStatic = (mCurrentElementArrayStorage == IndexStorageType::Static);
+    mRelevantDirtyBitsMask.set(gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA, isStatic);
+
+    return gl::NoError();
+}
+
+void VertexArray11::updateVertexAttribStorage(StateManager11 *stateManager,
+                                              size_t dirtyBit,
+                                              size_t attribIndex)
+{
+    const gl::VertexAttribute &attrib = mState.getVertexAttribute(attribIndex);
+    const gl::VertexBinding &binding  = mState.getBindingFromAttribIndex(attribIndex);
+
+    VertexStorageType newStorageType = ClassifyAttributeStorage(attrib, binding);
+
+    // Note: having an unchanged storage type doesn't mean the attribute is clean.
+    mAttribsToTranslate.set(attribIndex, newStorageType != VertexStorageType::DYNAMIC);
+
+    if (mAttributeStorageTypes[attribIndex] == newStorageType)
+        return;
+
+    mAttributeStorageTypes[attribIndex] = newStorageType;
+    mDynamicAttribsMask.set(attribIndex, newStorageType == VertexStorageType::DYNAMIC);
+
+    // Mark non-static buffers as irrelevant.
+    size_t bufferDataDirtyBit = (gl::VertexArray::DIRTY_BIT_BUFFER_DATA_0 + attribIndex);
+    mRelevantDirtyBitsMask.set(bufferDataDirtyBit, newStorageType == VertexStorageType::STATIC);
+
+    if (newStorageType == VertexStorageType::CURRENT_VALUE)
+    {
+        stateManager->invalidateCurrentValueAttrib(attribIndex);
     }
 }
 
 bool VertexArray11::hasActiveDynamicAttrib(const gl::Context *context)
 {
-    flushAttribUpdates(context);
     const auto &activeLocations =
         context->getGLState().getProgram()->getActiveAttribLocationsMask();
-    auto activeDynamicAttribs = (mDynamicAttribsMask & activeLocations);
+    gl::AttributesMask activeDynamicAttribs = (mDynamicAttribsMask & activeLocations);
     return activeDynamicAttribs.any();
 }
 
-gl::Error VertexArray11::updateDirtyAndDynamicAttribs(const gl::Context *context,
-                                                      VertexDataManager *vertexDataManager,
-                                                      const DrawCallVertexParams &vertexParams)
+gl::Error VertexArray11::updateDirtyAttribs(const gl::Context *context,
+                                            const gl::AttributesMask &activeDirtyAttribs)
 {
-    flushAttribUpdates(context);
+    const auto &glState  = context->getGLState();
+    const auto &attribs  = mState.getVertexAttributes();
+    const auto &bindings = mState.getVertexBindings();
 
-    const auto &glState         = context->getGLState();
-    const gl::Program *program  = glState.getProgram();
-    const auto &activeLocations = program->getActiveAttribLocationsMask();
-    const auto &attribs         = mState.getVertexAttributes();
-    const auto &bindings        = mState.getVertexBindings();
-    mAppliedNumViewsToDivisor =
-        (program != nullptr && program->usesMultiview()) ? program->getNumViews() : 1;
+    for (size_t dirtyAttribIndex : activeDirtyAttribs)
+    {
+        mAttribsToTranslate.reset(dirtyAttribIndex);
 
-    if (mAttribsToTranslate.any())
-    {
-        // Skip attrib locations the program doesn't use, saving for the next frame.
-        gl::AttributesMask dirtyActiveAttribs = (mAttribsToTranslate & activeLocations);
-
-        for (auto dirtyAttribIndex : dirtyActiveAttribs)
-        {
-            mAttribsToTranslate.reset(dirtyAttribIndex);
+        auto *translatedAttrib   = &mTranslatedAttribs[dirtyAttribIndex];
+        const auto &currentValue = glState.getVertexAttribCurrentValue(dirtyAttribIndex);
 
-            auto *translatedAttrib = &mTranslatedAttribs[dirtyAttribIndex];
-            const auto &currentValue = glState.getVertexAttribCurrentValue(dirtyAttribIndex);
+        // Record basic attrib info
+        translatedAttrib->attribute        = &attribs[dirtyAttribIndex];
+        translatedAttrib->binding          = &bindings[translatedAttrib->attribute->bindingIndex];
+        translatedAttrib->currentValueType = currentValue.Type;
+        translatedAttrib->divisor =
+            translatedAttrib->binding->getDivisor() * mAppliedNumViewsToDivisor;
 
-            // Record basic attrib info
-            translatedAttrib->attribute = &attribs[dirtyAttribIndex];
-            translatedAttrib->binding   = &bindings[translatedAttrib->attribute->bindingIndex];
-            translatedAttrib->currentValueType = currentValue.Type;
-            translatedAttrib->divisor =
-                translatedAttrib->binding->getDivisor() * mAppliedNumViewsToDivisor;
-
-            switch (mAttributeStorageTypes[dirtyAttribIndex])
+        switch (mAttributeStorageTypes[dirtyAttribIndex])
+        {
+            case VertexStorageType::DIRECT:
+                VertexDataManager::StoreDirectAttrib(translatedAttrib);
+                break;
+            case VertexStorageType::STATIC:
             {
-                case VertexStorageType::DIRECT:
-                    VertexDataManager::StoreDirectAttrib(translatedAttrib);
-                    break;
-                case VertexStorageType::STATIC:
-                {
-                    ANGLE_TRY(VertexDataManager::StoreStaticAttrib(context, translatedAttrib));
-                    break;
-                }
-                case VertexStorageType::CURRENT_VALUE:
-                    // Current value attribs are managed by the StateManager11.
-                    break;
-                default:
-                    UNREACHABLE();
-                    break;
+                ANGLE_TRY(VertexDataManager::StoreStaticAttrib(context, translatedAttrib));
+                break;
             }
+            case VertexStorageType::CURRENT_VALUE:
+                // Current value attribs are managed by the StateManager11.
+                break;
+            default:
+                UNREACHABLE();
+                break;
         }
     }
 
-    if (mDynamicAttribsMask.any())
-    {
-        auto activeDynamicAttribs = (mDynamicAttribsMask & activeLocations);
-        if (activeDynamicAttribs.none())
-        {
-            return gl::NoError();
-        }
+    return gl::NoError();
+}
 
-        for (auto dynamicAttribIndex : activeDynamicAttribs)
-        {
-            auto *dynamicAttrib = &mTranslatedAttribs[dynamicAttribIndex];
-            const auto &currentValue = glState.getVertexAttribCurrentValue(dynamicAttribIndex);
+gl::Error VertexArray11::updateDynamicAttribs(const gl::Context *context,
+                                              VertexDataManager *vertexDataManager,
+                                              const gl::DrawCallParams &drawCallParams,
+                                              const gl::AttributesMask &activeDynamicAttribs)
+{
+    const auto &glState  = context->getGLState();
+    const auto &attribs  = mState.getVertexAttributes();
+    const auto &bindings = mState.getVertexBindings();
+
+    ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
 
-            // Record basic attrib info
-            dynamicAttrib->attribute        = &attribs[dynamicAttribIndex];
-            dynamicAttrib->binding          = &bindings[dynamicAttrib->attribute->bindingIndex];
-            dynamicAttrib->currentValueType = currentValue.Type;
-            dynamicAttrib->divisor =
-                dynamicAttrib->binding->getDivisor() * mAppliedNumViewsToDivisor;
-        }
+    for (size_t dynamicAttribIndex : activeDynamicAttribs)
+    {
+        auto *dynamicAttrib      = &mTranslatedAttribs[dynamicAttribIndex];
+        const auto &currentValue = glState.getVertexAttribCurrentValue(dynamicAttribIndex);
 
-        ANGLE_TRY(vertexDataManager->storeDynamicAttribs(
-            context, &mTranslatedAttribs, activeDynamicAttribs, vertexParams.firstVertex(),
-            vertexParams.vertexCount(), vertexParams.instances()));
+        // Record basic attrib info
+        dynamicAttrib->attribute        = &attribs[dynamicAttribIndex];
+        dynamicAttrib->binding          = &bindings[dynamicAttrib->attribute->bindingIndex];
+        dynamicAttrib->currentValueType = currentValue.Type;
+        dynamicAttrib->divisor = dynamicAttrib->binding->getDivisor() * mAppliedNumViewsToDivisor;
     }
 
+    ANGLE_TRY(vertexDataManager->storeDynamicAttribs(
+        context, &mTranslatedAttribs, activeDynamicAttribs, drawCallParams.firstVertex(),
+        drawCallParams.vertexCount(), drawCallParams.instances()));
+
+    VertexDataManager::PromoteDynamicAttribs(context, mTranslatedAttribs, activeDynamicAttribs,
+                                             drawCallParams.vertexCount());
+
     return gl::NoError();
 }
 
 const std::vector<TranslatedAttribute> &VertexArray11::getTranslatedAttribs() const
 {
     return mTranslatedAttribs;
 }
 
-void VertexArray11::onSubjectStateChange(const gl::Context *context,
-                                         angle::SubjectIndex index,
-                                         angle::SubjectMessage message)
-{
-    if (index == mAttributeStorageTypes.size())
-    {
-        mCachedIndexInfoValid   = false;
-        mLastElementType        = GL_NONE;
-        mLastDrawElementsOffset = 0;
-    }
-    else
-    {
-        ASSERT(mAttributeStorageTypes[index] != VertexStorageType::CURRENT_VALUE);
-
-        // This can change a buffer's storage, we'll need to re-check.
-        mAttribsToUpdate.set(index);
-
-        // Changing the vertex attribute state can affect the vertex shader.
-        Renderer11 *renderer = GetImplAs<Context11>(context)->getRenderer();
-        renderer->getStateManager()->invalidateShaders();
-    }
-}
-
-void VertexArray11::clearDirtyAndPromoteDynamicAttribs(const gl::Context *context,
-                                                       const DrawCallVertexParams &vertexParams)
-{
-    const gl::State &state      = context->getGLState();
-    const gl::Program *program  = state.getProgram();
-    const auto &activeLocations = program->getActiveAttribLocationsMask();
-    mAttribsToUpdate &= ~activeLocations;
-
-    // Promote to static after we clear the dirty attributes, otherwise we can lose dirtyness.
-    auto activeDynamicAttribs = (mDynamicAttribsMask & activeLocations);
-    if (activeDynamicAttribs.any())
-    {
-        VertexDataManager::PromoteDynamicAttribs(context, mTranslatedAttribs, activeDynamicAttribs,
-                                                 vertexParams.vertexCount());
-    }
-}
-
 void VertexArray11::markAllAttributeDivisorsForAdjustment(int numViews)
 {
     if (mAppliedNumViewsToDivisor != numViews)
     {
         mAppliedNumViewsToDivisor = numViews;
-        mAttribsToUpdate.set();
+        mAttribsToTranslate.set();
     }
 }
 
-TranslatedIndexData *VertexArray11::getCachedIndexInfo()
+const TranslatedIndexData &VertexArray11::getCachedIndexInfo() const
 {
-    return &mCachedIndexInfo;
+    ASSERT(mCachedIndexInfo.valid());
+    return mCachedIndexInfo.value();
 }
 
-void VertexArray11::setCachedIndexInfoValid()
+void VertexArray11::updateCachedIndexInfo(const TranslatedIndexData &indexInfo)
 {
-    mCachedIndexInfoValid = true;
+    mCachedIndexInfo = indexInfo;
 }
 
 bool VertexArray11::isCachedIndexInfoValid() const
 {
-    return mCachedIndexInfoValid;
+    return mCachedIndexInfo.valid();
+}
+
+GLenum VertexArray11::getCachedDestinationIndexType() const
+{
+    return mCachedDestinationIndexType;
 }
 
 }  // namespace rx
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
@@ -8,94 +8,93 @@
 
 #ifndef LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_
 #define LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_
 
 #include "libANGLE/Framebuffer.h"
 #include "libANGLE/renderer/VertexArrayImpl.h"
 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
-#include "libANGLE/signal_utils.h"
 
 namespace rx
 {
 class Renderer11;
 
-class VertexArray11 : public VertexArrayImpl, public angle::ObserverInterface
+class VertexArray11 : public VertexArrayImpl
 {
   public:
     VertexArray11(const gl::VertexArrayState &data);
     ~VertexArray11() override;
     void destroy(const gl::Context *context) override;
 
-    void syncState(const gl::Context *context,
-                   const gl::VertexArray::DirtyBits &dirtyBits) override;
-    // This will flush any pending attrib updates and then check the dynamic attribs mask.
+    // Does not apply any state updates - these are done in syncStateForDraw which as access to
+    // the DrawCallParams before a draw.
+    gl::Error syncState(const gl::Context *context,
+                        const gl::VertexArray::DirtyBits &dirtyBits,
+                        const gl::VertexArray::DirtyAttribBitsArray &attribBits,
+                        const gl::VertexArray::DirtyBindingBitsArray &bindingBits) override;
+
+    // Applied buffer pointers are updated here.
+    gl::Error syncStateForDraw(const gl::Context *context,
+                               const gl::DrawCallParams &drawCallParams);
+
+    // This will check the dynamic attribs mask.
     bool hasActiveDynamicAttrib(const gl::Context *context);
-    gl::Error updateDirtyAndDynamicAttribs(const gl::Context *context,
-                                           VertexDataManager *vertexDataManager,
-                                           const DrawCallVertexParams &vertexParams);
-    void clearDirtyAndPromoteDynamicAttribs(const gl::Context *context,
-                                            const DrawCallVertexParams &vertexParams);
 
     const std::vector<TranslatedAttribute> &getTranslatedAttribs() const;
 
-    // Observer implementation
-    void onSubjectStateChange(const gl::Context *context,
-                              angle::SubjectIndex index,
-                              angle::SubjectMessage message) override;
-
     Serial getCurrentStateSerial() const { return mCurrentStateSerial; }
 
     // In case of a multi-view program change, we have to update all attributes so that the divisor
     // is adjusted.
     void markAllAttributeDivisorsForAdjustment(int numViews);
 
-    bool flushAttribUpdates(const gl::Context *context);
+    // Returns true if the element array buffer needs to be translated.
+    gl::Error updateElementArrayStorage(const gl::Context *context,
+                                        const gl::DrawCallParams &drawCallParams,
+                                        bool restartEnabled);
 
-    // Returns true if the element array buffer needs to be translated.
-    bool updateElementArrayStorage(const gl::Context *context,
-                                   GLenum elementType,
-                                   GLenum destElementType,
-                                   const void *indices);
-
-    TranslatedIndexData *getCachedIndexInfo();
-    void setCachedIndexInfoValid();
+    const TranslatedIndexData &getCachedIndexInfo() const;
+    void updateCachedIndexInfo(const TranslatedIndexData &indexInfo);
     bool isCachedIndexInfoValid() const;
 
+    GLenum getCachedDestinationIndexType() const;
+
   private:
-    void updateVertexAttribStorage(const gl::Context *context, size_t attribIndex);
+    void updateVertexAttribStorage(StateManager11 *stateManager,
+                                   size_t dirtyBit,
+                                   size_t attribIndex);
+    gl::Error updateDirtyAttribs(const gl::Context *context,
+                                 const gl::AttributesMask &activeDirtyAttribs);
+    gl::Error updateDynamicAttribs(const gl::Context *context,
+                                   VertexDataManager *vertexDataManager,
+                                   const gl::DrawCallParams &drawCallParams,
+                                   const gl::AttributesMask &activeDynamicAttribs);
 
     std::vector<VertexStorageType> mAttributeStorageTypes;
     std::vector<TranslatedAttribute> mTranslatedAttribs;
 
     // The mask of attributes marked as dynamic.
     gl::AttributesMask mDynamicAttribsMask;
 
-    // A mask of attributes that need to be re-evaluated.
-    gl::AttributesMask mAttribsToUpdate;
+    // Mask applied to dirty bits on syncState. If a bit is on, it is relevant.
+    gl::VertexArray::DirtyBits mRelevantDirtyBitsMask;
 
     // A set of attributes we know are dirty, and need to be re-translated.
     gl::AttributesMask mAttribsToTranslate;
 
-    // We need to keep a safe pointer to the Buffer so we can attach the correct dirty callbacks.
-    std::vector<gl::BindingPointer<gl::Buffer>> mCurrentArrayBuffers;
-    gl::BindingPointer<gl::Buffer> mCurrentElementArrayBuffer;
-
-    std::vector<angle::ObserverBinding> mOnArrayBufferDataDirty;
-    angle::ObserverBinding mOnElementArrayBufferDataDirty;
-
     Serial mCurrentStateSerial;
 
     // The numViews value used to adjust the divisor.
     int mAppliedNumViewsToDivisor;
 
     // If the index buffer needs re-streaming.
-    GLenum mLastElementType;
-    unsigned int mLastDrawElementsOffset;
+    Optional<GLenum> mLastDrawElementsType;
+    Optional<const void *> mLastDrawElementsIndices;
+    Optional<bool> mLastPrimitiveRestartEnabled;
     IndexStorageType mCurrentElementArrayStorage;
-    TranslatedIndexData mCachedIndexInfo;
-    bool mCachedIndexInfoValid;
+    Optional<TranslatedIndexData> mCachedIndexInfo;
+    GLenum mCachedDestinationIndexType;
 };
 
 }  // namespace rx
 
 #endif // LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
@@ -91,17 +91,17 @@ void VertexBuffer11::hintUnmapResource()
         mMappedResourceData = nullptr;
     }
 }
 
 gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib,
                                                 const gl::VertexBinding &binding,
                                                 GLenum currentValueType,
                                                 GLint start,
-                                                GLsizei count,
+                                                size_t count,
                                                 GLsizei instances,
                                                 unsigned int offset,
                                                 const uint8_t *sourceData)
 {
     if (!mBuffer.valid())
     {
         return gl::OutOfMemory() << "Internal vertex buffer is not initialized.";
     }
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h
@@ -26,17 +26,17 @@ class VertexBuffer11 : public VertexBuff
     gl::Error initialize(unsigned int size, bool dynamicUsage) override;
 
     // Warning: you should ensure binding really matches attrib.bindingIndex before using this
     // function.
     gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib,
                                     const gl::VertexBinding &binding,
                                     GLenum currentValueType,
                                     GLint start,
-                                    GLsizei count,
+                                    size_t count,
                                     GLsizei instances,
                                     unsigned int offset,
                                     const uint8_t *sourceData) override;
 
     unsigned int getBufferSize() const override;
     gl::Error setBufferSize(unsigned int size) override;
     gl::Error discard() override;
 
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -16,17 +16,16 @@
 #include "libANGLE/Context.h"
 #include "libANGLE/Framebuffer.h"
 #include "libANGLE/Program.h"
 #include "libANGLE/State.h"
 #include "libANGLE/VertexArray.h"
 #include "libANGLE/formatutils.h"
 #include "libANGLE/renderer/d3d/BufferD3D.h"
 #include "libANGLE/renderer/d3d/FramebufferD3D.h"
-#include "libANGLE/renderer/d3d/IndexBuffer.h"
 #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
 #include "libANGLE/renderer/d3d/d3d11/dxgi_support_table.h"
 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
 #include "libANGLE/renderer/driver_utils.h"
 #include "platform/Platform.h"
 #include "platform/WorkaroundsD3D.h"
@@ -2353,86 +2352,38 @@ bool UsePresentPathFast(const Renderer11
 
 bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled, GLenum type)
 {
     // We should never have to deal with primitive restart workaround issue with GL_UNSIGNED_INT
     // indices, since we restrict it via MAX_ELEMENT_INDEX.
     return (!primitiveRestartFixedIndexEnabled && type == GL_UNSIGNED_SHORT);
 }
 
-bool IsStreamingIndexData(const gl::Context *context, GLenum srcType)
-{
-    const auto &glState = context->getGLState();
-    gl::Buffer *glBuffer = glState.getVertexArray()->getElementArrayBuffer().get();
-
-    // Case 1: the indices are passed by pointer, which forces the streaming of index data
-    if (glBuffer == nullptr)
-    {
-        return true;
-    }
-
-    bool primitiveRestartWorkaround =
-        UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), srcType);
-
-    BufferD3D *buffer    = GetImplAs<BufferD3D>(glBuffer);
-    const GLenum dstType = (srcType == GL_UNSIGNED_INT || primitiveRestartWorkaround)
-                               ? GL_UNSIGNED_INT
-                               : GL_UNSIGNED_SHORT;
-
-    // Case 2a: the buffer can be used directly
-    if (buffer->supportsDirectBinding() && dstType == srcType)
-    {
-        return false;
-    }
-
-    // Case 2b: use a static translated copy or fall back to streaming
-    StaticIndexBufferInterface *staticBuffer = buffer->getStaticIndexBuffer();
-    if (staticBuffer == nullptr)
-    {
-        return true;
-    }
-
-    if ((staticBuffer->getBufferSize() == 0) || (staticBuffer->getIndexType() != dstType))
-    {
-        return true;
-    }
-
-    return false;
-}
-
 IndexStorageType ClassifyIndexStorage(const gl::State &glState,
                                       const gl::Buffer *elementArrayBuffer,
                                       GLenum elementType,
                                       GLenum destElementType,
-                                      unsigned int offset,
-                                      bool *needsTranslation)
+                                      unsigned int offset)
 {
     // No buffer bound means we are streaming from a client pointer.
     if (!elementArrayBuffer || !IsOffsetAligned(elementType, offset))
     {
-        *needsTranslation = true;
         return IndexStorageType::Dynamic;
     }
 
     // The buffer can be used directly if the storage supports it and no translation needed.
     BufferD3D *bufferD3D = GetImplAs<BufferD3D>(elementArrayBuffer);
     if (bufferD3D->supportsDirectBinding() && destElementType == elementType)
     {
-        *needsTranslation = false;
         return IndexStorageType::Direct;
     }
 
     // Use a static copy when available.
     StaticIndexBufferInterface *staticBuffer = bufferD3D->getStaticIndexBuffer();
     if (staticBuffer != nullptr)
     {
-        // Need to re-translate the static data if has never been used, or changed type.
-        *needsTranslation =
-            (staticBuffer->getBufferSize() == 0 || staticBuffer->getIndexType() != destElementType);
         return IndexStorageType::Static;
     }
 
     // Static buffer not available, fall back to streaming.
-    *needsTranslation = true;
     return IndexStorageType::Dynamic;
 }
-
 }  // namespace rx
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
@@ -28,17 +28,16 @@ class FramebufferAttachment;
 }
 
 namespace rx
 {
 class Renderer11;
 class RenderTarget11;
 struct Renderer11DeviceCaps;
 
-using RenderTargetArray = std::array<RenderTarget11 *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>;
 using RTVArray          = std::array<ID3D11RenderTargetView *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>;
 
 namespace gl_d3d11
 {
 
 D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha);
 D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp);
 UINT8 ConvertColorMask(bool maskRed, bool maskGreen, bool maskBlue, bool maskAlpha);
@@ -393,17 +392,16 @@ class TextureHelper11 : public Resource1
 enum class StagingAccess
 {
     READ,
     READ_WRITE,
 };
 
 bool UsePresentPathFast(const Renderer11 *renderer, const gl::FramebufferAttachment *colorbuffer);
 bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled, GLenum type);
-bool IsStreamingIndexData(const gl::Context *context, GLenum srcType);
 
 enum class IndexStorageType
 {
     // Dynamic indexes are re-streamed every frame. They come from a client data pointer or
     // from buffers that are updated frequently.
     Dynamic,
 
     // Static indexes are translated from the original storage once, and re-used multiple times.
@@ -416,14 +414,13 @@ enum class IndexStorageType
     // Not a real storage type.
     Invalid,
 };
 
 IndexStorageType ClassifyIndexStorage(const gl::State &glState,
                                       const gl::Buffer *elementArrayBuffer,
                                       GLenum elementType,
                                       GLenum destElementType,
-                                      unsigned int offset,
-                                      bool *needsTranslation);
+                                      unsigned int offset);
 
 }  // namespace rx
 
 #endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp
@@ -253,17 +253,18 @@ gl::Error Blit9::copy2D(const gl::Contex
     ANGLE_TRY(colorbuffer->getRenderTarget(context, &renderTarget9));
     ASSERT(renderTarget9);
 
     IDirect3DSurface9 *source = renderTarget9->getSurface();
     ASSERT(source);
 
     IDirect3DSurface9 *destSurface = nullptr;
     TextureStorage9 *storage9      = GetAs<TextureStorage9>(storage);
-    gl::Error error = storage9->getSurfaceLevel(context, GL_TEXTURE_2D, level, true, &destSurface);
+    gl::Error error =
+        storage9->getSurfaceLevel(context, gl::TextureTarget::_2D, level, true, &destSurface);
     if (error.isError())
     {
         SafeRelease(source);
         return error;
     }
     ASSERT(destSurface);
 
     gl::Error result =
@@ -276,17 +277,17 @@ gl::Error Blit9::copy2D(const gl::Contex
 }
 
 gl::Error Blit9::copyCube(const gl::Context *context,
                           const gl::Framebuffer *framebuffer,
                           const RECT &sourceRect,
                           GLenum destFormat,
                           const gl::Offset &destOffset,
                           TextureStorage *storage,
-                          GLenum target,
+                          gl::TextureTarget target,
                           GLint level)
 {
     gl::Error error = initialize();
     if (error.isError())
     {
         return error;
     }
 
@@ -325,17 +326,17 @@ gl::Error Blit9::copyCube(const gl::Cont
 
 gl::Error Blit9::copyTexture(const gl::Context *context,
                              const gl::Texture *source,
                              GLint sourceLevel,
                              const RECT &sourceRect,
                              GLenum destFormat,
                              const gl::Offset &destOffset,
                              TextureStorage *storage,
-                             GLenum destTarget,
+                             gl::TextureTarget destTarget,
                              GLint destLevel,
                              bool flipY,
                              bool premultiplyAlpha,
                              bool unmultiplyAlpha)
 {
     ANGLE_TRY(initialize());
 
     const TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
@@ -349,18 +350,18 @@ gl::Error Blit9::copyTexture(const gl::C
     TextureStorage9 *destStorage9 = GetAs<TextureStorage9>(storage);
     ASSERT(destStorage9);
 
     ASSERT(sourceLevel == 0);
     IDirect3DBaseTexture9 *sourceTexture = nullptr;
     ANGLE_TRY(sourceStorage9->getBaseTexture(context, &sourceTexture));
 
     IDirect3DSurface9 *sourceSurface = nullptr;
-    ANGLE_TRY(
-        sourceStorage9->getSurfaceLevel(context, GL_TEXTURE_2D, sourceLevel, true, &sourceSurface));
+    ANGLE_TRY(sourceStorage9->getSurfaceLevel(context, gl::TextureTarget::_2D, sourceLevel, true,
+                                              &sourceSurface));
 
     IDirect3DSurface9 *destSurface = nullptr;
     gl::Error error =
         destStorage9->getSurfaceLevel(context, destTarget, destLevel, true, &destSurface);
     if (error.isError())
     {
         SafeRelease(sourceSurface);
         return error;
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.h
@@ -6,18 +6,17 @@
 
 // Blit9.cpp: Surface copy utility class.
 
 #ifndef LIBANGLE_RENDERER_D3D_D3D9_BLIT9_H_
 #define LIBANGLE_RENDERER_D3D_D3D9_BLIT9_H_
 
 #include "common/angleutils.h"
 #include "libANGLE/Error.h"
-
-#include <GLES2/gl2.h>
+#include "libANGLE/PackedGLEnums.h"
 
 namespace gl
 {
 class Context;
 class Framebuffer;
 class Texture;
 struct Extents;
 struct Offset;
@@ -46,26 +45,26 @@ class Blit9 : angle::NonCopyable
                      TextureStorage *storage,
                      GLint level);
     gl::Error copyCube(const gl::Context *context,
                        const gl::Framebuffer *framebuffer,
                        const RECT &sourceRect,
                        GLenum destFormat,
                        const gl::Offset &destOffset,
                        TextureStorage *storage,
-                       GLenum target,
+                       gl::TextureTarget target,
                        GLint level);
     gl::Error copyTexture(const gl::Context *context,
                           const gl::Texture *source,
                           GLint sourceLevel,
                           const RECT &sourceRect,
                           GLenum destFormat,
                           const gl::Offset &destOffset,
                           TextureStorage *storage,
-                          GLenum destTarget,
+                          gl::TextureTarget destTarget,
                           GLint destLevel,
                           bool flipY,
                           bool premultiplyAlpha,
                           bool unmultiplyAlpha);
 
     // 2x2 box filter sample from source to dest.
     // Requires that source is RGB(A) and dest has the same format as source.
     gl::Error boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.cpp
@@ -58,23 +58,23 @@ ProgramImpl *Context9::createProgram(con
 
 FramebufferImpl *Context9::createFramebuffer(const gl::FramebufferState &data)
 {
     return new Framebuffer9(data, mRenderer);
 }
 
 TextureImpl *Context9::createTexture(const gl::TextureState &state)
 {
-    switch (state.getTarget())
+    switch (state.getType())
     {
-        case GL_TEXTURE_2D:
+        case gl::TextureType::_2D:
             return new TextureD3D_2D(state, mRenderer);
-        case GL_TEXTURE_CUBE_MAP:
+        case gl::TextureType::CubeMap:
             return new TextureD3D_Cube(state, mRenderer);
-        case GL_TEXTURE_EXTERNAL_OES:
+        case gl::TextureType::External:
             return new TextureD3D_External(state, mRenderer);
         default:
             UNREACHABLE();
     }
     return nullptr;
 }
 
 RenderbufferImpl *Context9::createRenderbuffer(const gl::RenderbufferState &state)
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
@@ -19,17 +19,16 @@
 #include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
 #include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h"
 #include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
 #include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
 #include "libANGLE/renderer/renderer_utils.h"
 
 namespace rx
 {
-
 Framebuffer9::Framebuffer9(const gl::FramebufferState &data, Renderer9 *renderer)
     : FramebufferD3D(data, renderer), mRenderer(renderer)
 {
     ASSERT(mRenderer != nullptr);
 }
 
 Framebuffer9::~Framebuffer9()
 {
@@ -56,30 +55,29 @@ gl::Error Framebuffer9::invalidateSub(co
 {
     // Shouldn't ever reach here in D3D9
     UNREACHABLE();
     return gl::NoError();
 }
 
 gl::Error Framebuffer9::clearImpl(const gl::Context *context, const ClearParameters &clearParams)
 {
-    const gl::FramebufferAttachment *colorAttachment        = mState.getColorAttachment(0);
-    const gl::FramebufferAttachment *depthStencilAttachment = mState.getDepthOrStencilAttachment();
-
-    ANGLE_TRY(mRenderer->applyRenderTarget(context, colorAttachment, depthStencilAttachment));
+    ANGLE_TRY(mRenderer->applyRenderTarget(context, mRenderTargetCache.getColors()[0],
+                                           mRenderTargetCache.getDepthStencil()));
 
     const gl::State &glState = context->getGLState();
     float nearZ              = glState.getNearPlane();
     float farZ = glState.getFarPlane();
     mRenderer->setViewport(glState.getViewport(), nearZ, farZ, GL_TRIANGLES,
                            glState.getRasterizerState().frontFace, true);
 
     mRenderer->setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled());
 
-    return mRenderer->clear(context, clearParams, colorAttachment, depthStencilAttachment);
+    return mRenderer->clear(context, clearParams, mRenderTargetCache.getColors()[0],
+                            mRenderTargetCache.getDepthStencil());
 }
 
 gl::Error Framebuffer9::readPixelsImpl(const gl::Context *context,
                                        const gl::Rectangle &area,
                                        GLenum format,
                                        GLenum type,
                                        size_t outputPitch,
                                        const gl::PixelPackState &pack,
@@ -106,25 +104,27 @@ gl::Error Framebuffer9::readPixelsImpl(c
                << "ReadPixels is unimplemented for multisampled framebuffer attachments.";
     }
 
     IDirect3DDevice9 *device = mRenderer->getDevice();
     ASSERT(device);
 
     HRESULT result;
     IDirect3DSurface9 *systemSurface = nullptr;
-    bool directToPixels = !pack.reverseRowOrder && pack.alignment <= 4 && mRenderer->getShareHandleSupport() &&
-                          area.x == 0 && area.y == 0 &&
-                          static_cast<UINT>(area.width) == desc.Width && static_cast<UINT>(area.height) == desc.Height &&
-                          desc.Format == D3DFMT_A8R8G8B8 && format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE;
+    bool directToPixels =
+        !pack.reverseRowOrder && pack.alignment <= 4 && mRenderer->getShareHandleSupport() &&
+        area.x == 0 && area.y == 0 && static_cast<UINT>(area.width) == desc.Width &&
+        static_cast<UINT>(area.height) == desc.Height && desc.Format == D3DFMT_A8R8G8B8 &&
+        format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE;
     if (directToPixels)
     {
         // Use the pixels ptr as a shared handle to write directly into client's memory
         result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format,
-                                                     D3DPOOL_SYSTEMMEM, &systemSurface, reinterpret_cast<void**>(&pixels));
+                                                     D3DPOOL_SYSTEMMEM, &systemSurface,
+                                                     reinterpret_cast<void **>(&pixels));
         if (FAILED(result))
         {
             // Try again without the shared handle
             directToPixels = false;
         }
     }
 
     if (!directToPixels)
@@ -403,9 +403,16 @@ GLenum Framebuffer9::getRenderTargetImpl
 }
 
 gl::Error Framebuffer9::getSamplePosition(size_t index, GLfloat *xy) const
 {
     UNREACHABLE();
     return gl::InternalError() << "getSamplePosition is unsupported to d3d9.";
 }
 
+gl::Error Framebuffer9::syncState(const gl::Context *context,
+                                  const gl::Framebuffer::DirtyBits &dirtyBits)
+{
+    ANGLE_TRY(FramebufferD3D::syncState(context, dirtyBits));
+    ANGLE_TRY(mRenderTargetCache.update(context, mState, dirtyBits));
+    return gl::NoError();
+}
 }  // namespace rx
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
@@ -4,17 +4,19 @@
 // found in the LICENSE file.
 //
 
 // Framebuffer9.h: Defines the Framebuffer9 class.
 
 #ifndef LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_
 #define LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_
 
+#include "libANGLE/renderer/RenderTargetCache.h"
 #include "libANGLE/renderer/d3d/FramebufferD3D.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
 
 namespace rx
 {
 class Renderer9;
 
 class Framebuffer9 : public FramebufferD3D
 {
   public:
@@ -27,16 +29,29 @@ class Framebuffer9 : public FramebufferD
                          const GLenum *attachments) override;
     gl::Error invalidateSub(const gl::Context *context,
                             size_t count,
                             const GLenum *attachments,
                             const gl::Rectangle &area) override;
 
     gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
 
+    gl::Error syncState(const gl::Context *context,
+                        const gl::Framebuffer::DirtyBits &dirtyBits) override;
+
+    const gl::AttachmentArray<RenderTarget9 *> &getCachedColorRenderTargets() const
+    {
+        return mRenderTargetCache.getColors();
+    }
+
+    const RenderTarget9 *getCachedDepthStencilRenderTarget() const
+    {
+        return mRenderTargetCache.getDepthStencil();
+    }
+
   private:
     gl::Error clearImpl(const gl::Context *context, const ClearParameters &clearParams) override;
 
     gl::Error readPixelsImpl(const gl::Context *context,
                              const gl::Rectangle &area,
                              GLenum format,
                              GLenum type,
                              size_t outputPitch,
@@ -51,13 +66,15 @@ class Framebuffer9 : public FramebufferD
                        bool blitDepth,
                        bool blitStencil,
                        GLenum filter,
                        const gl::Framebuffer *sourceFramebuffer) override;
 
     GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override;
 
     Renderer9 *const mRenderer;
+
+    RenderTargetCache<RenderTarget9> mRenderTargetCache;
 };
 
-}
+}  // namespace rx
 
 #endif // LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.cpp
@@ -232,33 +232,37 @@ gl::Error Image9::CopyImage(const gl::Co
                       unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
 
     destSurface->UnlockRect();
     sourceSurface->UnlockRect();
 
     return gl::NoError();
 }
 
-bool Image9::redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease)
+bool Image9::redefine(gl::TextureType type,
+                      GLenum internalformat,
+                      const gl::Extents &size,
+                      bool forceRelease)
 {
     // 3D textures are not supported by the D3D9 backend.
     ASSERT(size.depth <= 1);
 
     // Only 2D and cube texture are supported by the D3D9 backend.
-    ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_CUBE_MAP);
+    ASSERT(type == gl::TextureType::_2D || type == gl::TextureType::CubeMap);
 
     if (mWidth != size.width ||
         mHeight != size.height ||
         mDepth != size.depth ||
         mInternalFormat != internalformat ||
         forceRelease)
     {
         mWidth = size.width;
         mHeight = size.height;
         mDepth = size.depth;
+        mType           = type;
         mInternalFormat = internalformat;
 
         // compute the d3d format that will be used
         const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalformat);
         mD3DFormat = d3d9FormatInfo.texFormat;
         mRenderable = (d3d9FormatInfo.renderFormat != D3DFMT_UNKNOWN);
 
         SafeRelease(mSurface);
@@ -402,32 +406,33 @@ gl::Error Image9::getSurface(IDirect3DSu
 }
 
 gl::Error Image9::setManagedSurface2D(const gl::Context *context,
                                       TextureStorage *storage,
                                       int level)
 {
     IDirect3DSurface9 *surface = nullptr;
     TextureStorage9 *storage9  = GetAs<TextureStorage9>(storage);
-    gl::Error error = storage9->getSurfaceLevel(context, GL_TEXTURE_2D, level, false, &surface);
+    gl::Error error =
+        storage9->getSurfaceLevel(context, gl::TextureTarget::_2D, level, false, &surface);
     if (error.isError())
     {
         return error;
     }
     return setManagedSurface(surface);
 }
 
 gl::Error Image9::setManagedSurfaceCube(const gl::Context *context,
                                         TextureStorage *storage,
                                         int face,
                                         int level)
 {
     IDirect3DSurface9 *surface = nullptr;
     TextureStorage9 *storage9 = GetAs<TextureStorage9>(storage);
-    gl::Error error = storage9->getSurfaceLevel(context, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
+    gl::Error error = storage9->getSurfaceLevel(context, gl::CubeFaceIndexToTextureTarget(face),
                                                 level, false, &surface);
     if (error.isError())
     {
         return error;
     }
     return setManagedSurface(surface);
 }
 
@@ -541,20 +546,20 @@ gl::Error Image9::loadData(const gl::Con
                            const gl::PixelUnpackState &unpack,
                            GLenum type,
                            const void *input,
                            bool applySkipImages)
 {
     // 3D textures are not supported by the D3D9 backend.
     ASSERT(area.z == 0 && area.depth == 1);
 
-    const gl::InternalFormat &packFormat = gl::GetPackFormatInfo(mInternalFormat, type);
+    const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat);
     GLuint inputRowPitch                 = 0;
     ANGLE_TRY_RESULT(
-        packFormat.computeRowPitch(area.width, unpack.alignment, unpack.rowLength),
+        formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength),
         inputRowPitch);
     ASSERT(!applySkipImages);
     ASSERT(unpack.skipPixels == 0);
     ASSERT(unpack.skipRows == 0);
 
     const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
     ASSERT(d3dFormatInfo.loadFunction != nullptr);
 
@@ -584,17 +589,17 @@ gl::Error Image9::loadCompressedData(con
                                      const gl::Box &area,
                                      const void *input)
 {
     // 3D textures are not supported by the D3D9 backend.
     ASSERT(area.z == 0 && area.depth == 1);
 
     const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat);
     GLsizei inputRowPitch                = 0;
-    ANGLE_TRY_RESULT(formatInfo.computeRowPitch(area.width, 1, 0), inputRowPitch);
+    ANGLE_TRY_RESULT(formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0), inputRowPitch);
     GLsizei inputDepthPitch = 0;
     ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(area.height, 0, inputDepthPitch),
                      inputDepthPitch);
 
     const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
 
     ASSERT(area.x % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockWidth == 0);
     ASSERT(area.y % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockHeight == 0);
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.h
@@ -35,17 +35,20 @@ class Image9 : public ImageD3D
                                Image9 *dest,
                                Image9 *source,
                                const gl::Rectangle &sourceRect,
                                const gl::Offset &destOffset,
                                bool unpackFlipY,
                                bool unpackPremultiplyAlpha,
                                bool unpackUnmultiplyAlpha);
 
-    bool redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease) override;
+    bool redefine(gl::TextureType type,
+                  GLenum internalformat,
+                  const gl::Extents &size,
+                  bool forceRelease) override;
 
     D3DFORMAT getD3DFormat() const;
 
     bool isDirty() const override;
 
     gl::Error setManagedSurface2D(const gl::Context *context,
                                   TextureStorage *storage,
                                   int level) override;
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
@@ -116,20 +116,20 @@ Renderer9::Renderer9(egl::Display *displ
     mVertexDataManager = nullptr;
     mIndexDataManager  = nullptr;
     mLineLoopIB        = nullptr;
     mCountingIB        = nullptr;
 
     mMaxNullColorbufferLRU = 0;
     for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
     {
-        mNullColorbufferCache[i].lruCount = 0;
-        mNullColorbufferCache[i].width    = 0;
-        mNullColorbufferCache[i].height   = 0;
-        mNullColorbufferCache[i].buffer   = nullptr;
+        mNullRenderTargetCache[i].lruCount     = 0;
+        mNullRenderTargetCache[i].width        = 0;
+        mNullRenderTargetCache[i].height       = 0;
+        mNullRenderTargetCache[i].renderTarget = nullptr;
     }
 
     mAppliedVertexShader  = nullptr;
     mAppliedPixelShader   = nullptr;
     mAppliedProgramSerial = 0;
 
     gl::InitializeDebugAnnotations(&mAnnotator);
 }
@@ -932,17 +932,17 @@ gl::Error Renderer9::fastCopyBufferToTex
 }
 
 gl::Error Renderer9::setSamplerState(const gl::Context *context,
                                      gl::ShaderType type,
                                      int index,
                                      gl::Texture *texture,
                                      const gl::SamplerState &samplerState)
 {
-    CurSamplerState &appliedSampler = (type == gl::SHADER_FRAGMENT)
+    CurSamplerState &appliedSampler = (type == gl::ShaderType::Fragment)
                                           ? mCurPixelSamplerStates[index]
                                           : mCurVertexSamplerStates[index];
 
     // Make sure to add the level offset for our tiny compressed texture workaround
     TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
 
     TextureStorage *storage = nullptr;
     ANGLE_TRY(textureD3D->getNativeTexture(context, &storage));
@@ -950,17 +950,17 @@ gl::Error Renderer9::setSamplerState(con
     // Storage should exist, texture should be complete
     ASSERT(storage);
 
     DWORD baseLevel = texture->getBaseLevel() + storage->getTopLevel();
 
     if (appliedSampler.forceSet || appliedSampler.baseLevel != baseLevel ||
         memcmp(&samplerState, &appliedSampler, sizeof(gl::SamplerState)) != 0)
     {
-        int d3dSamplerOffset = (type == gl::SHADER_FRAGMENT) ? 0 : D3DVERTEXTEXTURESAMPLER0;
+        int d3dSamplerOffset = (type == gl::ShaderType::Fragment) ? 0 : D3DVERTEXTEXTURESAMPLER0;
         int d3dSampler       = index + d3dSamplerOffset;
 
         mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU,
                                  gl_d3d9::ConvertTextureWrap(samplerState.wrapS));
         mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV,
                                  gl_d3d9::ConvertTextureWrap(samplerState.wrapT));
 
         mDevice->SetSamplerState(
@@ -990,23 +990,23 @@ gl::Error Renderer9::setSamplerState(con
     return gl::NoError();
 }
 
 gl::Error Renderer9::setTexture(const gl::Context *context,
                                 gl::ShaderType type,
                                 int index,
                                 gl::Texture *texture)
 {
-    int d3dSamplerOffset = (type == gl::SHADER_FRAGMENT) ? 0 : D3DVERTEXTEXTURESAMPLER0;
+    int d3dSamplerOffset = (type == gl::ShaderType::Fragment) ? 0 : D3DVERTEXTEXTURESAMPLER0;
     int d3dSampler                    = index + d3dSamplerOffset;
     IDirect3DBaseTexture9 *d3dTexture = nullptr;
     bool forceSetTexture              = false;
 
     std::vector<uintptr_t> &appliedTextures =
-        (type == gl::SHADER_FRAGMENT) ? mCurPixelTextures : mCurVertexTextures;
+        (type == gl::ShaderType::Fragment) ? mCurPixelTextures : mCurVertexTextures;
 
     if (texture)
     {
         TextureD3D *textureImpl = GetImplAs<TextureD3D>(texture);
 
         TextureStorage *texStorage = nullptr;
         ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage));
 
@@ -1036,19 +1036,22 @@ gl::Error Renderer9::setTexture(const gl
 
 gl::Error Renderer9::updateState(const gl::Context *context, GLenum drawMode)
 {
     const auto &glState = context->getGLState();
 
     // Applies the render target surface, depth stencil surface, viewport rectangle and
     // scissor rectangle to the renderer
     gl::Framebuffer *framebuffer = glState.getDrawFramebuffer();
-    ASSERT(framebuffer && !framebuffer->hasAnyDirtyBit() && framebuffer->cachedComplete());
-
-    ANGLE_TRY(applyRenderTarget(context, framebuffer));
+    ASSERT(framebuffer && !framebuffer->hasAnyDirtyBit());
+
+    Framebuffer9 *framebuffer9 = GetImplAs<Framebuffer9>(framebuffer);
+
+    ANGLE_TRY(applyRenderTarget(context, framebuffer9->getCachedColorRenderTargets()[0],
+                                framebuffer9->getCachedDepthStencilRenderTarget()));
 
     // Setting viewport state
     setViewport(glState.getViewport(), glState.getNearPlane(), glState.getFarPlane(), drawMode,
                 glState.getRasterizerState().frontFace, false);
 
     // Setting scissors state
     setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled());
 
@@ -1153,119 +1156,99 @@ bool Renderer9::applyPrimitiveType(GLenu
         default:
             UNREACHABLE();
             return false;
     }
 
     return mPrimitiveCount > 0;
 }
 
-gl::Error Renderer9::getNullColorbuffer(const gl::Context *context,
-                                        const gl::FramebufferAttachment *depthbuffer,
-                                        const gl::FramebufferAttachment **outColorBuffer)
+gl::Error Renderer9::getNullColorRenderTarget(const gl::Context *context,
+                                              const RenderTarget9 *depthRenderTarget,
+                                              const RenderTarget9 **outColorRenderTarget)
 {
-    ASSERT(depthbuffer);
-
-    const gl::Extents &size = depthbuffer->getSize();
+    ASSERT(depthRenderTarget);
+
+    const gl::Extents &size = depthRenderTarget->getExtents();
 
     // search cached nullcolorbuffers
     for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
     {
-        if (mNullColorbufferCache[i].buffer != nullptr &&
-            mNullColorbufferCache[i].width == size.width &&
-            mNullColorbufferCache[i].height == size.height)
+        if (mNullRenderTargetCache[i].renderTarget != nullptr &&
+            mNullRenderTargetCache[i].width == size.width &&
+            mNullRenderTargetCache[i].height == size.height)
         {
-            mNullColorbufferCache[i].lruCount = ++mMaxNullColorbufferLRU;
-            *outColorBuffer                   = mNullColorbufferCache[i].buffer;
+            mNullRenderTargetCache[i].lruCount = ++mMaxNullColorbufferLRU;
+            *outColorRenderTarget              = mNullRenderTargetCache[i].renderTarget;
             return gl::NoError();
         }
     }
 
-    auto *implFactory = context->getImplementation();
-
-    gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(implFactory, 0);
-    gl::Error error = nullRenderbuffer->setStorage(context, GL_NONE, size.width, size.height);
-    if (error.isError())
-    {
-        SafeDelete(nullRenderbuffer);
-        return error;
-    }
-
-    gl::FramebufferAttachment *nullbuffer = new gl::FramebufferAttachment(
-        context, GL_RENDERBUFFER, GL_NONE, gl::ImageIndex::MakeInvalid(), nullRenderbuffer);
+    RenderTargetD3D *nullRenderTarget = nullptr;
+    ANGLE_TRY(createRenderTarget(size.width, size.height, GL_NONE, 0, &nullRenderTarget));
 
     // add nullbuffer to the cache
-    NullColorbufferCacheEntry *oldest = &mNullColorbufferCache[0];
+    NullRenderTargetCacheEntry *oldest = &mNullRenderTargetCache[0];
     for (int i = 1; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
     {
-        if (mNullColorbufferCache[i].lruCount < oldest->lruCount)
+        if (mNullRenderTargetCache[i].lruCount < oldest->lruCount)
         {
-            oldest = &mNullColorbufferCache[i];
+            oldest = &mNullRenderTargetCache[i];
         }
     }
 
-    delete oldest->buffer;
-    oldest->buffer   = nullbuffer;
+    SafeDelete(oldest->renderTarget);
+    oldest->renderTarget = GetAs<RenderTarget9>(nullRenderTarget);
     oldest->lruCount = ++mMaxNullColorbufferLRU;
     oldest->width    = size.width;
     oldest->height   = size.height;
 
-    *outColorBuffer = nullbuffer;
+    *outColorRenderTarget = oldest->renderTarget;
     return gl::NoError();
 }
 
 gl::Error Renderer9::applyRenderTarget(const gl::Context *context,
-                                       const gl::FramebufferAttachment *colorAttachment,
-                                       const gl::FramebufferAttachment *depthStencilAttachment)
+                                       const RenderTarget9 *colorRenderTargetIn,
+                                       const RenderTarget9 *depthStencilRenderTarget)
 {
-    const gl::FramebufferAttachment *renderAttachment = colorAttachment;
-
     // if there is no color attachment we must synthesize a NULL colorattachment
     // to keep the D3D runtime happy.  This should only be possible if depth texturing.
-    if (renderAttachment == nullptr)
+    const RenderTarget9 *colorRenderTarget = colorRenderTargetIn;
+    if (colorRenderTarget == nullptr)
     {
-        ANGLE_TRY(getNullColorbuffer(context, depthStencilAttachment, &renderAttachment));
+        ANGLE_TRY(getNullColorRenderTarget(context, depthStencilRenderTarget, &colorRenderTarget));
     }
-    ASSERT(renderAttachment != nullptr);
+    ASSERT(colorRenderTarget != nullptr);
 
     size_t renderTargetWidth     = 0;
     size_t renderTargetHeight    = 0;
     D3DFORMAT renderTargetFormat = D3DFMT_UNKNOWN;
 
-    RenderTarget9 *renderTarget = nullptr;
-    ANGLE_TRY(renderAttachment->getRenderTarget(context, &renderTarget));
-    ASSERT(renderTarget);
-
     bool renderTargetChanged        = false;
-    unsigned int renderTargetSerial = renderTarget->getSerial();
+    unsigned int renderTargetSerial = colorRenderTarget->getSerial();
     if (renderTargetSerial != mAppliedRenderTargetSerial)
     {
         // Apply the render target on the device
-        IDirect3DSurface9 *renderTargetSurface = renderTarget->getSurface();
+        IDirect3DSurface9 *renderTargetSurface = colorRenderTarget->getSurface();
         ASSERT(renderTargetSurface);
 
         mDevice->SetRenderTarget(0, renderTargetSurface);
         SafeRelease(renderTargetSurface);
 
-        renderTargetWidth  = renderTarget->getWidth();
-        renderTargetHeight = renderTarget->getHeight();
-        renderTargetFormat = renderTarget->getD3DFormat();
+        renderTargetWidth  = colorRenderTarget->getWidth();
+        renderTargetHeight = colorRenderTarget->getHeight();
+        renderTargetFormat = colorRenderTarget->getD3DFormat();
 
         mAppliedRenderTargetSerial = renderTargetSerial;
         renderTargetChanged        = true;
     }
 
-    RenderTarget9 *depthStencilRenderTarget = nullptr;
-    unsigned int depthStencilSerial         = 0;
-
-    if (depthStencilAttachment != nullptr)
+    unsigned int depthStencilSerial = 0;
+    if (depthStencilRenderTarget != nullptr)
     {
-        ANGLE_TRY(depthStencilAttachment->getRenderTarget(context, &depthStencilRenderTarget));
-        ASSERT(depthStencilRenderTarget);
-
         depthStencilSerial = depthStencilRenderTarget->getSerial();
     }
 
     if (depthStencilSerial != mAppliedDepthStencilSerial || !mDepthStencilInitialized)
     {
         unsigned int depthSize   = 0;
         unsigned int stencilSize = 0;
 
@@ -1273,18 +1256,21 @@ gl::Error Renderer9::applyRenderTarget(c
         if (depthStencilRenderTarget)
         {
             IDirect3DSurface9 *depthStencilSurface = depthStencilRenderTarget->getSurface();
             ASSERT(depthStencilSurface);
 
             mDevice->SetDepthStencilSurface(depthStencilSurface);
             SafeRelease(depthStencilSurface);
 
-            depthSize   = depthStencilAttachment->getDepthSize();
-            stencilSize = depthStencilAttachment->getStencilSize();
+            const gl::InternalFormat &format =
+                gl::GetSizedInternalFormatInfo(depthStencilRenderTarget->getInternalFormat());
+
+            depthSize   = format.depthBits;
+            stencilSize = format.stencilBits;
         }
         else
         {
             mDevice->SetDepthStencilSurface(nullptr);
         }
 
         mStateManager.updateDepthSizeIfChanged(mDepthStencilInitialized, depthSize);
         mStateManager.updateStencilSizeIfChanged(mDepthStencilInitialized, stencilSize);
@@ -1299,23 +1285,16 @@ gl::Error Renderer9::applyRenderTarget(c
         mStateManager.forceSetScissorState();
         mStateManager.setRenderTargetBounds(renderTargetWidth, renderTargetHeight);
         mRenderTargetDescInitialized = true;
     }
 
     return gl::NoError();
 }
 
-gl::Error Renderer9::applyRenderTarget(const gl::Context *context,
-                                       const gl::Framebuffer *framebuffer)
-{
-    return applyRenderTarget(context, framebuffer->getColorbuffer(0),
-                             framebuffer->getDepthOrStencilbuffer());
-}
-
 gl::Error Renderer9::applyVertexBuffer(const gl::Context *context,
                                        GLenum mode,
                                        GLint first,
                                        GLsizei count,
                                        GLsizei instances,
                                        TranslatedIndexData * /*indexInfo*/)
 {
     const gl::State &state = context->getGLState();
@@ -1333,21 +1312,22 @@ gl::Error Renderer9::applyVertexBuffer(c
 // Applies the indices and element array bindings to the Direct3D 9 device
 gl::Error Renderer9::applyIndexBuffer(const gl::Context *context,
                                       const void *indices,
                                       GLsizei count,
                                       GLenum mode,
                                       GLenum type,
                                       TranslatedIndexData *indexInfo)
 {
-    gl::VertexArray *vao           = context->getGLState().getVertexArray();
-    gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
-    const auto &lazyIndexRange     = context->getParams<gl::HasIndexRange>();
-
-    GLenum dstType = GetIndexTranslationDestType(type, lazyIndexRange, false);
+    gl::VertexArray *vao                     = context->getGLState().getVertexArray();
+    gl::Buffer *elementArrayBuffer           = vao->getElementArrayBuffer().get();
+    const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
+
+    GLenum dstType = GL_NONE;
+    ANGLE_TRY(GetIndexTranslationDestType(context, drawCallParams, false, &dstType));
 
     ANGLE_TRY(mIndexDataManager->prepareIndexData(context, type, dstType, count, elementArrayBuffer,
                                                   indices, indexInfo));
 
     // Directly binding the storage buffer is not supported for d3d9
     ASSERT(indexInfo->storage == nullptr);
 
     if (indexInfo->serial != mAppliedIBSerial)
@@ -1412,18 +1392,20 @@ gl::Error Renderer9::drawElementsImpl(co
                                       GLenum type,
                                       const void *indices,
                                       GLsizei instances)
 {
     TranslatedIndexData indexInfo;
 
     ANGLE_TRY(applyIndexBuffer(context, indices, count, mode, type, &indexInfo));
 
-    const auto &lazyIndexRange       = context->getParams<gl::HasIndexRange>();
-    const gl::IndexRange &indexRange = lazyIndexRange.getIndexRange().value();
+    const auto &drawCallParams = context->getParams<gl::DrawCallParams>();
+    ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
+
+    const gl::IndexRange &indexRange = drawCallParams.getIndexRange();
     size_t vertexCount               = indexRange.vertexCount();
     ANGLE_TRY(applyVertexBuffer(context, mode, static_cast<GLsizei>(indexRange.start),
                                 static_cast<GLsizei>(vertexCount), instances, &indexInfo));
 
     startScene();
 
     int minIndex = static_cast<int>(indexRange.start);
 
@@ -1819,18 +1801,18 @@ gl::Error Renderer9::applyShaders(const 
     // Driver uniforms
     mStateManager.setShaderConstants();
 
     return gl::NoError();
 }
 
 gl::Error Renderer9::applyUniforms(ProgramD3D *programD3D)
 {
-    // Skip updates if we're not dirty. Note that D3D9 cannot have compute.
-    if (!programD3D->areVertexUniformsDirty() && !programD3D->areFragmentUniformsDirty())
+    // Skip updates if we're not dirty. Note that D3D9 cannot have compute or geometry.
+    if (!programD3D->anyShaderUniformsDirty())
     {
         return gl::NoError();
     }
 
     const auto &uniformArray = programD3D->getD3DUniforms();
 
     for (const D3DUniform *targetUniform : uniformArray)
     {
@@ -1922,18 +1904,18 @@ void Renderer9::applyUniformnbv(const D3
         vector[i][3] = (v[4 * i + 3] == GL_FALSE) ? 0.0f : 1.0f;
     }
 
     applyUniformnfv(targetUniform, (GLfloat *)vector);
 }
 
 gl::Error Renderer9::clear(const gl::Context *context,
                            const ClearParameters &clearParams,
-                           const gl::FramebufferAttachment *colorBuffer,
-                           const gl::FramebufferAttachment *depthStencilBuffer)
+                           const RenderTarget9 *colorRenderTarget,
+                           const RenderTarget9 *depthStencilRenderTarget)
 {
     if (clearParams.colorType != GL_FLOAT)
     {
         // Clearing buffers with non-float values is not supported by Renderer9 and ES 2.0
         UNREACHABLE();
         return gl::InternalError();
     }
 
@@ -1948,58 +1930,42 @@ gl::Error Renderer9::clear(const gl::Con
             return gl::InternalError();
         }
     }
 
     float depth   = gl::clamp01(clearParams.depthValue);
     DWORD stencil = clearParams.stencilValue & 0x000000FF;
 
     unsigned int stencilUnmasked = 0x0;
-    if (clearParams.clearStencil && depthStencilBuffer->getStencilSize() > 0)
+    if (clearParams.clearStencil && depthStencilRenderTarget)
     {
-        ASSERT(depthStencilBuffer != nullptr);
-
-        RenderTargetD3D *stencilRenderTarget = nullptr;
-        gl::Error error = depthStencilBuffer->getRenderTarget(context, &stencilRenderTarget);
-        if (error.isError())
+        const gl::InternalFormat &depthStencilFormat =
+            gl::GetSizedInternalFormatInfo(depthStencilRenderTarget->getInternalFormat());
+        if (depthStencilFormat.stencilBits > 0)
         {
-            return error;
+            const d3d9::D3DFormat &d3dFormatInfo =
+                d3d9::GetD3DFormatInfo(depthStencilRenderTarget->getD3DFormat());
+            stencilUnmasked = (0x1 << d3dFormatInfo.stencilBits) - 1;
         }
-
-        RenderTarget9 *stencilRenderTarget9 = GetAs<RenderTarget9>(stencilRenderTarget);
-        ASSERT(stencilRenderTarget9);
-
-        const d3d9::D3DFormat &d3dFormatInfo =
-            d3d9::GetD3DFormatInfo(stencilRenderTarget9->getD3DFormat());
-        stencilUnmasked = (0x1 << d3dFormatInfo.stencilBits) - 1;
     }
 
     const bool needMaskedStencilClear =
         clearParams.clearStencil &&
         (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
 
     bool needMaskedColorClear = false;
     D3DCOLOR color            = D3DCOLOR_ARGB(255, 0, 0, 0);
     if (clearColor)
     {
-        ASSERT(colorBuffer != nullptr);
-
-        RenderTargetD3D *colorRenderTarget = nullptr;
-        gl::Error error = colorBuffer->getRenderTarget(context, &colorRenderTarget);
-        if (error.isError())
-        {
-            return error;
-        }
-
-        RenderTarget9 *colorRenderTarget9 = GetAs<RenderTarget9>(colorRenderTarget);
-        ASSERT(colorRenderTarget9);
-
-        const gl::InternalFormat &formatInfo = *colorBuffer->getFormat().info;
+        ASSERT(colorRenderTarget != nullptr);
+
+        const gl::InternalFormat &formatInfo =
+            gl::GetSizedInternalFormatInfo(colorRenderTarget->getInternalFormat());
         const d3d9::D3DFormat &d3dFormatInfo =
-            d3d9::GetD3DFormatInfo(colorRenderTarget9->getD3DFormat());
+            d3d9::GetD3DFormatInfo(colorRenderTarget->getD3DFormat());
 
         color =
             D3DCOLOR_ARGB(gl::unorm<8>((formatInfo.alphaBits == 0 && d3dFormatInfo.alphaBits > 0)
                                            ? 1.0f
                                            : clearParams.colorF.alpha),
                           gl::unorm<8>((formatInfo.redBits == 0 && d3dFormatInfo.redBits > 0)
                                            ? 0.0f
                                            : clearParams.colorF.red),
@@ -2235,21 +2201,17 @@ void Renderer9::releaseDeviceResources()
     SafeDelete(mBlit);
     SafeDelete(mVertexDataManager);
     SafeDelete(mIndexDataManager);
     SafeDelete(mLineLoopIB);
     SafeDelete(mCountingIB);
 
     for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
     {
-        if (mNullColorbufferCache[i].buffer)
-        {
-            mNullColorbufferCache[i].buffer->detach(mDisplay->getProxyContext());
-        }
-        SafeDelete(mNullColorbufferCache[i].buffer);
+        SafeDelete(mNullRenderTargetCache[i].renderTarget);
     }
 }
 
 // set notify to true to broadcast a message to all contexts of the device loss
 bool Renderer9::testDeviceLost()
 {
     HRESULT status = getDeviceStatusCode();
     return FAILED(status);
@@ -2375,17 +2337,17 @@ bool Renderer9::isRemovedDeviceResettabl
     {
         D3DCAPS9 deviceCaps;
         HRESULT result = d3d9Ex->GetDeviceCaps(mAdapter, mDeviceType, &deviceCaps);
         success        = SUCCEEDED(result);
     }
 
     SafeRelease(d3d9Ex);
 #else
-    ASSERT(UNREACHABLE());
+    UNREACHABLE();
 #endif
 
     return success;
 }
 
 bool Renderer9::resetRemovedDevice()
 {
     // From http://msdn.microsoft.com/en-us/library/windows/desktop/bb172554(v=vs.85).aspx:
@@ -2506,17 +2468,17 @@ gl::Error Renderer9::copyImage2D(const g
 }
 
 gl::Error Renderer9::copyImageCube(const gl::Context *context,
                                    const gl::Framebuffer *framebuffer,
                                    const gl::Rectangle &sourceRect,
                                    GLenum destFormat,
                                    const gl::Offset &destOffset,
                                    TextureStorage *storage,
-                                   GLenum target,
+                                   gl::TextureTarget target,
                                    GLint level)
 {
     RECT rect;
     rect.left   = sourceRect.x;
     rect.top    = sourceRect.y;
     rect.right  = sourceRect.x + sourceRect.width;
     rect.bottom = sourceRect.y + sourceRect.height;
 
@@ -2553,17 +2515,17 @@ gl::Error Renderer9::copyImage2DArray(co
 gl::Error Renderer9::copyTexture(const gl::Context *context,
                                  const gl::Texture *source,
                                  GLint sourceLevel,
                                  const gl::Rectangle &sourceRect,
                                  GLenum destFormat,
                                  GLenum destType,
                                  const gl::Offset &destOffset,
                                  TextureStorage *storage,
-                                 GLenum destTarget,
+                                 gl::TextureTarget destTarget,
                                  GLint destLevel,
                                  bool unpackFlipY,
                                  bool unpackPremultiplyAlpha,
                                  bool unpackUnmultiplyAlpha)
 {
     RECT rect;
     rect.left   = sourceRect.x;
     rect.top    = sourceRect.y;
@@ -2689,28 +2651,28 @@ gl::Error Renderer9::loadExecutable(cons
                                     bool separatedOutputBuffers,
                                     ShaderExecutableD3D **outExecutable)
 {
     // Transform feedback is not supported in ES2 or D3D9
     ASSERT(streamOutVaryings.empty());
 
     switch (type)
     {
-        case gl::SHADER_VERTEX:
+        case gl::ShaderType::Vertex:
         {
             IDirect3DVertexShader9 *vshader = nullptr;
             gl::Error error = createVertexShader((DWORD *)function, length, &vshader);
             if (error.isError())
             {
                 return error;
             }
             *outExecutable = new ShaderExecutable9(function, length, vshader);
         }
         break;
-        case gl::SHADER_FRAGMENT:
+        case gl::ShaderType::Fragment:
         {
             IDirect3DPixelShader9 *pshader = nullptr;
             gl::Error error                = createPixelShader((DWORD *)function, length, &pshader);
             if (error.isError())
             {
                 return error;
             }
             *outExecutable = new ShaderExecutable9(function, length, pshader);
@@ -2734,20 +2696,20 @@ gl::Error Renderer9::compileToExecutable
 {
     // Transform feedback is not supported in ES2 or D3D9
     ASSERT(streamOutVaryings.empty());
 
     std::stringstream profileStream;
 
     switch (type)
     {
-        case gl::SHADER_VERTEX:
+        case gl::ShaderType::Vertex:
             profileStream << "vs";
             break;
-        case gl::SHADER_FRAGMENT:
+        case gl::ShaderType::Fragment:
             profileStream << "ps";
             break;
         default:
             UNREACHABLE();
             return gl::InternalError();
     }
 
     profileStream << "_" << ((getMajorShaderModel() >= 3) ? 3 : 2);
@@ -3031,17 +2993,17 @@ VertexConversionType Renderer9::getVerte
 
 GLenum Renderer9::getVertexComponentType(gl::VertexFormatType vertexFormatType) const
 {
     return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatType).componentType;
 }
 
 gl::ErrorOrResult<unsigned int> Renderer9::getVertexSpaceRequired(const gl::VertexAttribute &attrib,
                                                                   const gl::VertexBinding &binding,
-                                                                  GLsizei count,
+                                                                  size_t count,
                                                                   GLsizei instances) const
 {
     if (!attrib.enabled)
     {
         return 16u;
     }
 
     gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, GL_FLOAT);
@@ -3254,41 +3216,43 @@ gl::Error Renderer9::applyTextures(const
             const gl::SamplerState &samplerState =
                 samplerObject ? samplerObject->getSamplerState() : texture->getSamplerState();
 
             ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, texture, samplerState));
             ANGLE_TRY(setTexture(context, shaderType, samplerIndex, texture));
         }
         else
         {
-            GLenum textureType = programD3D->getSamplerTextureType(shaderType, samplerIndex);
+            gl::TextureType textureType =
+                programD3D->getSamplerTextureType(shaderType, samplerIndex);
 
             // Texture is not sampler complete or it is in use by the framebuffer.  Bind the
             // incomplete texture.
             gl::Texture *incompleteTexture = nullptr;
             ANGLE_TRY(getIncompleteTexture(context, textureType, &incompleteTexture));
             ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, incompleteTexture,
                                       incompleteTexture->getSamplerState()));
             ANGLE_TRY(setTexture(context, shaderType, samplerIndex, incompleteTexture));
         }
     }
 
     // Set all the remaining textures to NULL
-    size_t samplerCount = (shaderType == gl::SHADER_FRAGMENT) ? caps.maxTextureImageUnits
-                                                              : caps.maxVertexTextureImageUnits;
+    size_t samplerCount = (shaderType == gl::ShaderType::Fragment)
+                              ? caps.maxTextureImageUnits
+                              : caps.maxVertexTextureImageUnits;
 
     // TODO(jmadill): faster way?
     for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
     {
         ANGLE_TRY(setTexture(context, shaderType, static_cast<int>(samplerIndex), nullptr));
     }
 
     return gl::NoError();
 }
 
 gl::Error Renderer9::applyTextures(const gl::Context *context)
 {
-    ANGLE_TRY(applyTextures(context, gl::SHADER_VERTEX));
-    ANGLE_TRY(applyTextures(context, gl::SHADER_FRAGMENT));
+    ANGLE_TRY(applyTextures(context, gl::ShaderType::Vertex));
+    ANGLE_TRY(applyTextures(context, gl::ShaderType::Fragment));
     return gl::NoError();
 }
 
 }  // namespace rx
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
@@ -31,16 +31,17 @@ class AttributeMap;
 }
 
 namespace rx
 {
 class Blit9;
 class Context9;
 class IndexDataManager;
 class ProgramD3D;
+class RenderTarget9;
 class StreamingIndexBufferInterface;
 class StaticIndexBufferInterface;
 class VertexDataManager;
 struct ClearParameters;
 struct D3DUniform;
 struct TranslatedAttribute;
 
 enum D3D9InitError
@@ -134,20 +135,19 @@ class Renderer9 : public RendererD3D
     void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
     void setViewport(const gl::Rectangle &viewport,
                      float zNear,
                      float zFar,
                      GLenum drawMode,
                      GLenum frontFace,
                      bool ignoreViewport);
 
-    gl::Error applyRenderTarget(const gl::Context *context, const gl::Framebuffer *frameBuffer);
     gl::Error applyRenderTarget(const gl::Context *context,
-                                const gl::FramebufferAttachment *colorAttachment,
-                                const gl::FramebufferAttachment *depthStencilAttachment);
+                                const RenderTarget9 *colorRenderTarget,
+                                const RenderTarget9 *depthStencilRenderTarget);
     gl::Error applyUniforms(ProgramD3D *programD3D);
     bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize);
     gl::Error applyVertexBuffer(const gl::Context *context,
                                 GLenum mode,
                                 GLint first,
                                 GLsizei count,
                                 GLsizei instances,
                                 TranslatedIndexData *indexInfo);
@@ -155,18 +155,18 @@ class Renderer9 : public RendererD3D
                                const void *indices,
                                GLsizei count,
                                GLenum mode,
                                GLenum type,
                                TranslatedIndexData *indexInfo);
 
     gl::Error clear(const gl::Context *context,
                     const ClearParameters &clearParams,
-                    const gl::FramebufferAttachment *colorBuffer,
-                    const gl::FramebufferAttachment *depthStencilBuffer);
+                    const RenderTarget9 *colorRenderTarget,
+                    const RenderTarget9 *depthStencilRenderTarget);
 
     void markAllStateDirty();
 
     // lost device
     bool testDeviceLost() override;
     bool testDeviceResettable() override;
 
     VendorID getVendorId() const;
@@ -196,17 +196,17 @@ class Renderer9 : public RendererD3D
                           TextureStorage *storage,
                           GLint level) override;
     gl::Error copyImageCube(const gl::Context *context,
                             const gl::Framebuffer *framebuffer,
                             const gl::Rectangle &sourceRect,
                             GLenum destFormat,
                             const gl::Offset &destOffset,
                             TextureStorage *storage,
-                            GLenum target,
+                            gl::TextureTarget target,
                             GLint level) override;
     gl::Error copyImage3D(const gl::Context *context,
                           const gl::Framebuffer *framebuffer,
                           const gl::Rectangle &sourceRect,
                           GLenum destFormat,
                           const gl::Offset &destOffset,
                           TextureStorage *storage,
                           GLint level) override;
@@ -221,17 +221,17 @@ class Renderer9 : public RendererD3D
     gl::Error copyTexture(const gl::Context *context,
                           const gl::Texture *source,
                           GLint sourceLevel,
                           const gl::Rectangle &sourceRect,
                           GLenum destFormat,
                           GLenum destType,
                           const gl::Offset &destOffset,
                           TextureStorage *storage,
-                          GLenum destTarget,
+                          gl::TextureTarget destTarget,
                           GLint destLevel,
                           bool unpackFlipY,
                           bool unpackPremultiplyAlpha,
                           bool unpackUnmultiplyAlpha) override;
     gl::Error copyCompressedTexture(const gl::Context *context,
                                     const gl::Texture *source,
                                     GLint sourceLevel,
                                     TextureStorage *storage,
@@ -341,17 +341,17 @@ class Renderer9 : public RendererD3D
     VertexConversionType getVertexConversionType(
         gl::VertexFormatType vertexFormatType) const override;
     GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const override;
 
     // Warning: you should ensure binding really matches attrib.bindingIndex before using this
     // function.
     gl::ErrorOrResult<unsigned int> getVertexSpaceRequired(const gl::VertexAttribute &attrib,
                                                            const gl::VertexBinding &binding,
-                                                           GLsizei count,
+                                                           size_t count,
                                                            GLsizei instances) const override;
 
     gl::Error copyToRenderTarget(IDirect3DSurface9 *dest,
                                  IDirect3DSurface9 *source,
                                  bool fromManaged);
 
     RendererClass getRendererClass() const override;
 
@@ -431,19 +431,19 @@ class Renderer9 : public RendererD3D
                                 GLsizei count,
                                 GLenum type,
                                 const void *indices,
                                 int minIndex,
                                 gl::Buffer *elementArrayBuffer);
 
     gl::Error getCountingIB(size_t count, StaticIndexBufferInterface **outIB);
 
-    gl::Error getNullColorbuffer(const gl::Context *context,
-                                 const gl::FramebufferAttachment *depthbuffer,
-                                 const gl::FramebufferAttachment **outColorBuffer);
+    gl::Error getNullColorRenderTarget(const gl::Context *context,
+                                       const RenderTarget9 *depthRenderTarget,
+                                       const RenderTarget9 **outColorRenderTarget);
 
     D3DPOOL getBufferPool(DWORD usage) const;
 
     HMODULE mD3d9Module;
 
     egl::Error initializeDevice();
     D3DPRESENT_PARAMETERS getDefaultPresentParameters();
     void releaseDeviceResources();
@@ -518,23 +518,26 @@ class Renderer9 : public RendererD3D
     IndexDataManager *mIndexDataManager;
     StreamingIndexBufferInterface *mLineLoopIB;
     StaticIndexBufferInterface *mCountingIB;
 
     enum
     {
         NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12
     };
-    struct NullColorbufferCacheEntry
+    struct NullRenderTargetCacheEntry
     {
         UINT lruCount;
         int width;
         int height;
-        gl::FramebufferAttachment *buffer;
-    } mNullColorbufferCache[NUM_NULL_COLORBUFFER_CACHE_ENTRIES];
+        RenderTarget9 *renderTarget;
+    };
+
+    std::array<NullRenderTargetCacheEntry, NUM_NULL_COLORBUFFER_CACHE_ENTRIES>
+        mNullRenderTargetCache;
     UINT mMaxNullColorbufferLRU;
 
     std::vector<TranslatedAttribute> mTranslatedAttribCache;
 
     DebugAnnotator9 mAnnotator;
 };
 
 }  // namespace rx
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp
@@ -149,22 +149,22 @@ TextureStorage9_2D::~TextureStorage9_2D(
     {
         SafeDelete(renderTarget);
     }
 }
 
 // Increments refcount on surface.
 // caller must Release() the returned surface
 gl::Error TextureStorage9_2D::getSurfaceLevel(const gl::Context *context,
-                                              GLenum target,
+                                              gl::TextureTarget target,
                                               int level,
                                               bool dirty,
                                               IDirect3DSurface9 **outSurface)
 {
-    ASSERT(target == GL_TEXTURE_2D);
+    ASSERT(target == gl::TextureTarget::_2D);
 
     IDirect3DBaseTexture9 *baseTexture = nullptr;
     gl::Error error                    = getBaseTexture(context, &baseTexture);
     if (error.isError())
     {
         return error;
     }
 
@@ -199,17 +199,17 @@ gl::Error TextureStorage9_2D::getRenderT
         IDirect3DBaseTexture9 *baseTexture = nullptr;
         gl::Error error                    = getBaseTexture(context, &baseTexture);
         if (error.isError())
         {
             return error;
         }
 
         IDirect3DSurface9 *surface = nullptr;
-        error = getSurfaceLevel(context, GL_TEXTURE_2D, index.mipIndex, false, &surface);
+        error = getSurfaceLevel(context, gl::TextureTarget::_2D, index.mipIndex, false, &surface);
         if (error.isError())
         {
             return error;
         }
 
         size_t textureMipLevel = mTopLevel + index.mipIndex;
         size_t mipWidth        = std::max<size_t>(mTextureWidth >> textureMipLevel, 1u);
         size_t mipHeight       = std::max<size_t>(mTextureHeight >> textureMipLevel, 1u);
@@ -225,24 +225,25 @@ gl::Error TextureStorage9_2D::getRenderT
     return gl::NoError();
 }
 
 gl::Error TextureStorage9_2D::generateMipmap(const gl::Context *context,
                                              const gl::ImageIndex &sourceIndex,
                                              const gl::ImageIndex &destIndex)
 {
     IDirect3DSurface9 *upper = nullptr;
-    gl::Error error = getSurfaceLevel(context, GL_TEXTURE_2D, sourceIndex.mipIndex, false, &upper);
+    gl::Error error =
+        getSurfaceLevel(context, gl::TextureTarget::_2D, sourceIndex.mipIndex, false, &upper);
     if (error.isError())
     {
         return error;
     }
 
     IDirect3DSurface9 *lower = nullptr;
-    error = getSurfaceLevel(context, GL_TEXTURE_2D, destIndex.mipIndex, true, &lower);
+    error = getSurfaceLevel(context, gl::TextureTarget::_2D, destIndex.mipIndex, true, &lower);
     if (error.isError())
     {
         SafeRelease(upper);
         return error;
     }
 
     ASSERT(upper && lower);
     error = mRenderer->boxFilter(upper, lower);
@@ -285,24 +286,24 @@ gl::Error TextureStorage9_2D::copyToStor
     ASSERT(destStorage);
 
     TextureStorage9_2D *dest9 = GetAs<TextureStorage9_2D>(destStorage);
 
     int levels = getLevelCount();
     for (int i = 0; i < levels; ++i)
     {
         IDirect3DSurface9 *srcSurf = nullptr;
-        gl::Error error            = getSurfaceLevel(context, GL_TEXTURE_2D, i, false, &srcSurf);
+        gl::Error error = getSurfaceLevel(context, gl::TextureTarget::_2D, i, false, &srcSurf);
         if (error.isError())
         {
             return error;
         }
 
         IDirect3DSurface9 *dstSurf = nullptr;
-        error = dest9->getSurfaceLevel(context, GL_TEXTURE_2D, i, true, &dstSurf);
+        error = dest9->getSurfaceLevel(context, gl::TextureTarget::_2D, i, true, &dstSurf);
         if (error.isError())
         {
             SafeRelease(srcSurf);
             return error;
         }
 
         error = mRenderer->copyToRenderTarget(dstSurf, srcSurf, isManaged());
 
@@ -331,22 +332,22 @@ TextureStorage9_EGLImage::TextureStorage
     mMipLevels      = mTopLevel + 1;
 }
 
 TextureStorage9_EGLImage::~TextureStorage9_EGLImage()
 {
 }
 
 gl::Error TextureStorage9_EGLImage::getSurfaceLevel(const gl::Context *context,
-                                                    GLenum target,
+                                                    gl::TextureTarget target,
                                                     int level,
                                                     bool,
                                                     IDirect3DSurface9 **outSurface)
 {
-    ASSERT(target == GL_TEXTURE_2D);
+    ASSERT(target == gl::TextureTarget::_2D);
     ASSERT(level == 0);
 
     RenderTargetD3D *renderTargetD3D = nullptr;
     gl::Error error                  = mImage->getRenderTarget(context, &renderTargetD3D);
     if (error.isError())
     {
         return error;
     }
@@ -472,17 +473,17 @@ TextureStorage9_Cube::~TextureStorage9_C
     {
         SafeDelete(mRenderTarget[i]);
     }
 }
 
 // Increments refcount on surface.
 // caller must Release() the returned surface
 gl::Error TextureStorage9_Cube::getSurfaceLevel(const gl::Context *context,
-                                                GLenum target,
+                                                gl::TextureTarget target,
                                                 int level,
                                                 bool dirty,
                                                 IDirect3DSurface9 **outSurface)
 {
     IDirect3DBaseTexture9 *baseTexture = nullptr;
     gl::Error error                    = getBaseTexture(context, &baseTexture);
     if (error.isError())
     {
@@ -512,17 +513,18 @@ gl::Error TextureStorage9_Cube::getSurfa
 
 gl::Error TextureStorage9_Cube::getRenderTarget(const gl::Context *context,
                                                 const gl::ImageIndex &index,
                                                 RenderTargetD3D **outRT)
 {
     ASSERT(outRT);
     ASSERT(index.mipIndex == 0);
 
-    ASSERT(index.type == GL_TEXTURE_CUBE_MAP && gl::IsCubeMapTextureTarget(index.target));
+    ASSERT(index.type == gl::TextureType::CubeMap &&
+           gl::TextureTargetToType(index.target) == gl::TextureType::CubeMap);
     const size_t renderTargetIndex = index.cubeMapFaceIndex();
 
     if (mRenderTarget[renderTargetIndex] == nullptr && isRenderTarget())
     {
         IDirect3DBaseTexture9 *baseTexture = nullptr;
         gl::Error error                    = getBaseTexture(context, &baseTexture);
         if (error.isError())
         {
@@ -605,31 +607,29 @@ gl::Error TextureStorage9_Cube::getBaseT
 gl::Error TextureStorage9_Cube::copyToStorage(const gl::Context *context,
                                               TextureStorage *destStorage)
 {
     ASSERT(destStorage);
 
     TextureStorage9_Cube *dest9 = GetAs<TextureStorage9_Cube>(destStorage);
 
     int levels = getLevelCount();
-    for (int f = 0; f < static_cast<int>(gl::CUBE_FACE_COUNT); f++)
+    for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets())
     {
         for (int i = 0; i < levels; i++)
         {
             IDirect3DSurface9 *srcSurf = nullptr;
-            gl::Error error =
-                getSurfaceLevel(context, GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false, &srcSurf);
+            gl::Error error            = getSurfaceLevel(context, face, i, false, &srcSurf);
             if (error.isError())
             {
                 return error;
             }
 
             IDirect3DSurface9 *dstSurf = nullptr;
-            error = dest9->getSurfaceLevel(context, GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true,
-                                           &dstSurf);
+            error                      = dest9->getSurfaceLevel(context, face, i, true, &dstSurf);
             if (error.isError())
             {
                 SafeRelease(srcSurf);
                 return error;
             }
 
             error = mRenderer->copyToRenderTarget(dstSurf, srcSurf, isManaged());
 
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h
@@ -28,20 +28,20 @@ class TextureStorage9 : public TextureSt
     ~TextureStorage9() override;
 
     static DWORD GetTextureUsage(GLenum internalformat, bool renderTarget);
 
     D3DPOOL getPool() const;
     DWORD getUsage() const;
 
     virtual gl::Error getSurfaceLevel(const gl::Context *context,
-                                      GLenum target,
+                                      gl::TextureTarget target,
                                       int level,
                                       bool dirty,
-                                      IDirect3DSurface9 **outSurface) = 0;
+                                      IDirect3DSurface9 **outSurface)    = 0;
     virtual gl::Error getBaseTexture(const gl::Context *context,
                                      IDirect3DBaseTexture9 **outTexture) = 0;
 
     int getTopLevel() const override;
     bool isRenderTarget() const override;
     bool isManaged() const override;
     bool supportsNativeMipmapFunction() const override;
     int getLevelCount() const override;
@@ -74,17 +74,17 @@ class TextureStorage9 : public TextureSt
 class TextureStorage9_2D : public TextureStorage9
 {
   public:
     TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchain);
     TextureStorage9_2D(Renderer9 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
     ~TextureStorage9_2D() override;
 
     gl::Error getSurfaceLevel(const gl::Context *context,
-                              GLenum target,
+                              gl::TextureTarget target,
                               int level,
                               bool dirty,
                               IDirect3DSurface9 **outSurface) override;
     gl::Error getRenderTarget(const gl::Context *context,
                               const gl::ImageIndex &index,
                               RenderTargetD3D **outRT) override;
     gl::Error getBaseTexture(const gl::Context *context,
                              IDirect3DBaseTexture9 **outTexture) override;
@@ -100,17 +100,17 @@ class TextureStorage9_2D : public Textur
 
 class TextureStorage9_EGLImage final : public TextureStorage9
 {
   public:
     TextureStorage9_EGLImage(Renderer9 *renderer, EGLImageD3D *image, RenderTarget9 *renderTarget9);
     ~TextureStorage9_EGLImage() override;
 
     gl::Error getSurfaceLevel(const gl::Context *context,
-                              GLenum target,
+                              gl::TextureTarget target,
                               int level,
                               bool dirty,
                               IDirect3DSurface9 **outSurface) override;
     gl::Error getRenderTarget(const gl::Context *context,
                               const gl::ImageIndex &index,
                               RenderTargetD3D **outRT) override;
     gl::Error getBaseTexture(const gl::Context *context,
                              IDirect3DBaseTexture9 **outTexture) override;
@@ -125,17 +125,17 @@ class TextureStorage9_EGLImage final : p
 
 class TextureStorage9_Cube : public TextureStorage9
 {
   public:
     TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly);
     ~TextureStorage9_Cube() override;
 
     gl::Error getSurfaceLevel(const gl::Context *context,
-                              GLenum target,
+                              gl::TextureTarget target,
                               int level,
                               bool dirty,
                               IDirect3DSurface9 **outSurface) override;
     gl::Error getRenderTarget(const gl::Context *context,
                               const gl::ImageIndex &index,
                               RenderTargetD3D **outRT) override;
     gl::Error getBaseTexture(const gl::Context *context,
                              IDirect3DBaseTexture9 **outTexture) override;
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h
@@ -18,29 +18,34 @@ namespace rx
 {
 class Renderer9;
 
 class VertexArray9 : public VertexArrayImpl
 {
   public:
     VertexArray9(const gl::VertexArrayState &data) : VertexArrayImpl(data) {}
 
-    void syncState(const gl::Context *context,
-                   const gl::VertexArray::DirtyBits &dirtyBits) override;
+    gl::Error syncState(const gl::Context *context,
+                        const gl::VertexArray::DirtyBits &dirtyBits,
+                        const gl::VertexArray::DirtyAttribBitsArray &attribBits,
+                        const gl::VertexArray::DirtyBindingBitsArray &bindingBits) override;
 
     ~VertexArray9() override {}
 
     Serial getCurrentStateSerial() const { return mCurrentStateSerial; }
 
   private:
     Serial mCurrentStateSerial;
 };
 
-inline void VertexArray9::syncState(const gl::Context *context,
-                                    const gl::VertexArray::DirtyBits &dirtyBits)
+inline gl::Error VertexArray9::syncState(const gl::Context *context,
+                                         const gl::VertexArray::DirtyBits &dirtyBits,
+                                         const gl::VertexArray::DirtyAttribBitsArray &attribBits,
+                                         const gl::VertexArray::DirtyBindingBitsArray &bindingBits)
 {
     ASSERT(dirtyBits.any());
     Renderer9 *renderer = GetImplAs<Context9>(context)->getRenderer();
     mCurrentStateSerial = renderer->generateSerial();
+    return gl::NoError();
 }
-}
+}  // namespace rx
 
 #endif // LIBANGLE_RENDERER_D3D_D3D9_VERTEXARRAY9_H_
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp
@@ -56,28 +56,28 @@ gl::Error VertexBuffer9::initialize(unsi
     mDynamicUsage = dynamicUsage;
     return gl::NoError();
 }
 
 gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib,
                                                const gl::VertexBinding &binding,
                                                GLenum currentValueType,
                                                GLint start,
-                                               GLsizei count,
+                                               size_t count,
                                                GLsizei instances,
                                                unsigned int offset,
                                                const uint8_t *sourceData)
 {
     if (!mVertexBuffer)
     {
         return gl::OutOfMemory() << "Internal vertex buffer is not initialized.";
     }
 
-    int inputStride = static_cast<int>(gl::ComputeVertexAttributeStride(attrib, binding));
-    int elementSize = static_cast<int>(gl::ComputeVertexAttributeTypeSize(attrib));
+    size_t inputStride = gl::ComputeVertexAttributeStride(attrib, binding);
+    size_t elementSize = gl::ComputeVertexAttributeTypeSize(attrib);
 
     DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0;
 
     uint8_t *mapPtr = nullptr;
 
     auto errorOrMapSize = mRenderer->getVertexSpaceRequired(attrib, binding, count, instances);
     if (errorOrMapSize.isError())
     {
@@ -100,17 +100,17 @@ gl::Error VertexBuffer9::storeVertexAttr
     }
 
     gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, currentValueType);
     const d3d9::VertexFormat &d3dVertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormatType);
     bool needsConversion = (d3dVertexInfo.conversionType & VERTEX_CONVERT_CPU) > 0;
 
     if (!needsConversion && inputStride == elementSize)
     {
-        size_t copySize = static_cast<size_t>(count) * static_cast<size_t>(inputStride);
+        size_t copySize = count * inputStride;
         memcpy(mapPtr, input, copySize);
     }
     else
     {
         d3dVertexInfo.copyFunction(input, inputStride, count, mapPtr);
     }
 
     mVertexBuffer->Unlock();
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h
@@ -23,17 +23,17 @@ class VertexBuffer9 : public VertexBuffe
     gl::Error initialize(unsigned int size, bool dynamicUsage) override;
 
     // Warning: you should ensure binding really matches attrib.bindingIndex before using this
     // function.
     gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib,
                                     const gl::VertexBinding &binding,
                                     GLenum currentValueType,
                                     GLint start,
-                                    GLsizei count,
+                                    size_t count,
                                     GLsizei instances,
                                     unsigned int offset,
                                     const uint8_t *sourceData) override;
 
     unsigned int getBufferSize() const override;
     gl::Error setBufferSize(unsigned int size) override;
     gl::Error discard() override;
 
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
@@ -151,41 +151,42 @@ D3DCULL ConvertCullMode(gl::CullFaceMode
             break;
         default:
             UNREACHABLE();
     }
 
     return cull;
 }
 
-D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace)
+D3DCUBEMAP_FACES ConvertCubeFace(gl::TextureTarget cubeFace)
 {
     D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X;
 
     switch (cubeFace)
     {
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-        face = D3DCUBEMAP_FACE_POSITIVE_X;
-        break;
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-        face = D3DCUBEMAP_FACE_NEGATIVE_X;
-        break;
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-        face = D3DCUBEMAP_FACE_POSITIVE_Y;
-        break;
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-        face = D3DCUBEMAP_FACE_NEGATIVE_Y;
-        break;
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-        face = D3DCUBEMAP_FACE_POSITIVE_Z;
-        break;
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-        face = D3DCUBEMAP_FACE_NEGATIVE_Z;
-        break;
-      default: UNREACHABLE();
+        case gl::TextureTarget::CubeMapPositiveX:
+            face = D3DCUBEMAP_FACE_POSITIVE_X;
+            break;
+        case gl::TextureTarget::CubeMapNegativeX:
+            face = D3DCUBEMAP_FACE_NEGATIVE_X;
+            break;
+        case gl::TextureTarget::CubeMapPositiveY:
+            face = D3DCUBEMAP_FACE_POSITIVE_Y;
+            break;
+        case gl::TextureTarget::CubeMapNegativeY:
+            face = D3DCUBEMAP_FACE_NEGATIVE_Y;
+            break;
+        case gl::TextureTarget::CubeMapPositiveZ:
+            face = D3DCUBEMAP_FACE_POSITIVE_Z;
+            break;
+        case gl::TextureTarget::CubeMapNegativeZ:
+            face = D3DCUBEMAP_FACE_NEGATIVE_Z;
+            break;
+        default:
+            UNREACHABLE();
     }
 
     return face;
 }
 
 DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
 {
     return (red   ? D3DCOLORWRITEENABLE_RED   : 0) |
--- a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h
@@ -29,17 +29,17 @@ namespace gl_d3d9
 
 D3DCMPFUNC ConvertComparison(GLenum comparison);
 D3DCOLOR ConvertColor(gl::ColorF color);
 D3DBLEND ConvertBlendFunc(GLenum blend);
 D3DBLENDOP ConvertBlendOp(GLenum blendOp);
 D3DSTENCILOP ConvertStencilOp(GLenum stencilOp);
 D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap);
 D3DCULL ConvertCullMode(gl::CullFaceMode cullFace, GLenum frontFace);
-D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace);
+D3DCUBEMAP_FACES ConvertCubeFace(gl::TextureTarget cubeFace);
 DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha);
 D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy);
 void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter,
                       float *d3dLodBias, float maxAnisotropy, size_t baseLevel);
 D3DQUERYTYPE ConvertQueryType(GLenum queryType);
 
 D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples);
 
--- a/gfx/angle/checkout/src/libANGLE/renderer/load_functions_table_autogen.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/load_functions_table_autogen.cpp
@@ -143,16 +143,28 @@ LoadImageFunctionInfo ALPHA8_EXT_to_R8G8
         case GL_UNSIGNED_BYTE:
             return LoadImageFunctionInfo(LoadA8ToRGBA8, true);
         default:
             UNREACHABLE();
             return LoadImageFunctionInfo(UnreachableLoadFunction, true);
     }
 }
 
+LoadImageFunctionInfo ALPHA8_EXT_to_R8_UNORM(GLenum type)
+{
+    switch (type)
+    {
+        case GL_UNSIGNED_BYTE:
+            return LoadImageFunctionInfo(LoadToNative<GLubyte, 1>, false);
+        default:
+            UNREACHABLE();
+            return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+    }
+}
+
 LoadImageFunctionInfo BGR565_ANGLEX_to_B5G6R5_UNORM(GLenum type)
 {
     switch (type)
     {
         case GL_UNSIGNED_BYTE:
             return LoadImageFunctionInfo(LoadToNative<GLushort, 1>, false);
         case GL_UNSIGNED_SHORT_5_6_5:
             return LoadImageFunctionInfo(LoadRGB565ToBGR565, true);
@@ -643,40 +655,64 @@ LoadImageFunctionInfo LUMINANCE32F_EXT_t
         case GL_FLOAT:
             return LoadImageFunctionInfo(LoadL32FToRGBA32F, true);
         default:
             UNREACHABLE();
             return LoadImageFunctionInfo(UnreachableLoadFunction, true);
     }
 }
 
-LoadImageFunctionInfo LUMINANCE8_ALPHA8_EXT_to_default(GLenum type)
+LoadImageFunctionInfo LUMINANCE8_ALPHA8_EXT_to_R8G8B8A8_UNORM(GLenum type)
 {
     switch (type)
     {
         case GL_UNSIGNED_BYTE:
             return LoadImageFunctionInfo(LoadLA8ToRGBA8, true);
         default:
             UNREACHABLE();
             return LoadImageFunctionInfo(UnreachableLoadFunction, true);
     }
 }
 
-LoadImageFunctionInfo LUMINANCE8_EXT_to_default(GLenum type)
+LoadImageFunctionInfo LUMINANCE8_ALPHA8_EXT_to_R8G8_UNORM(GLenum type)
+{
+    switch (type)
+    {
+        case GL_UNSIGNED_BYTE:
+            return LoadImageFunctionInfo(LoadToNative<GLubyte, 2>, false);
+        default:
+            UNREACHABLE();
+            return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+    }
+}
+
+LoadImageFunctionInfo LUMINANCE8_EXT_to_R8G8B8A8_UNORM(GLenum type)
 {
     switch (type)
     {
         case GL_UNSIGNED_BYTE:
             return LoadImageFunctionInfo(LoadL8ToRGBA8, true);
         default:
             UNREACHABLE();
             return LoadImageFunctionInfo(UnreachableLoadFunction, true);
     }
 }
 
+LoadImageFunctionInfo LUMINANCE8_EXT_to_R8_UNORM(GLenum type)
+{
+    switch (type)
+    {
+        case GL_UNSIGNED_BYTE:
+            return LoadImageFunctionInfo(LoadToNative<GLubyte, 1>, false);
+        default:
+            UNREACHABLE();
+            return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+    }
+}
+
 LoadImageFunctionInfo LUMINANCE_ALPHA_to_R16G16B16A16_FLOAT(GLenum type)
 {
     switch (type)
     {
         case GL_HALF_FLOAT:
             return LoadImageFunctionInfo(LoadLA16FToRGBA16F, true);
         case GL_HALF_FLOAT_OES:
             return LoadImageFunctionInfo(LoadLA16FToRGBA16F, true);
@@ -1201,30 +1237,54 @@ LoadImageFunctionInfo RGB565_to_B5G6R5_U
         case GL_UNSIGNED_SHORT_5_6_5:
             return LoadImageFunctionInfo(LoadToNative<GLushort, 1>, false);
         default:
             UNREACHABLE();
             return LoadImageFunctionInfo(UnreachableLoadFunction, true);
     }
 }
 
+LoadImageFunctionInfo RGB565_to_R5G6B5_UNORM(GLenum type)
+{
+    switch (type)
+    {
+        case GL_UNSIGNED_SHORT_5_6_5:
+            return LoadImageFunctionInfo(LoadToNative<GLushort, 1>, false);
+        default:
+            UNREACHABLE();
+            return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+    }
+}
+
 LoadImageFunctionInfo RGB565_to_R8G8B8A8_UNORM(GLenum type)
 {
     switch (type)
     {
         case GL_UNSIGNED_BYTE:
             return LoadImageFunctionInfo(LoadToNative3To4<GLubyte, 0xFF>, true);
         case GL_UNSIGNED_SHORT_5_6_5:
             return LoadImageFunctionInfo(LoadR5G6B5ToRGBA8, true);
         default:
             UNREACHABLE();
             return LoadImageFunctionInfo(UnreachableLoadFunction, true);
     }
 }
 
+LoadImageFunctionInfo RGB5_A1_to_A1R5G5B5_UNORM(GLenum type)
+{
+    switch (type)
+    {
+        case GL_UNSIGNED_SHORT_5_5_5_1:
+            return LoadImageFunctionInfo(LoadRGB5A1ToA1RGB5, true);
+        default:
+            UNREACHABLE();
+            return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+    }
+}
+
 LoadImageFunctionInfo RGB5_A1_to_B5G5R5A1_UNORM(GLenum type)
 {
     switch (type)
     {
         case GL_UNSIGNED_BYTE:
             return LoadImageFunctionInfo(LoadRGBA8ToBGR5A1, true);
         case GL_UNSIGNED_INT_2_10_10_10_REV:
             return LoadImageFunctionInfo(LoadRGB10A2ToBGR5A1, true);
@@ -1572,16 +1632,18 @@ LoadFunctionMap GetLoadFunctionsMap(GLen
         case GL_ALPHA8_EXT:
         {
             switch (angleFormat)
             {
                 case Format::ID::A8_UNORM:
                     return ALPHA8_EXT_to_A8_UNORM;
                 case Format::ID::R8G8B8A8_UNORM:
                     return ALPHA8_EXT_to_R8G8B8A8_UNORM;
+                case Format::ID::R8_UNORM:
+                    return ALPHA8_EXT_to_R8_UNORM;
                 default:
                     break;
             }
             break;
         }
         case GL_BGR565_ANGLEX:
         {
             switch (angleFormat)
@@ -1862,19 +1924,41 @@ LoadFunctionMap GetLoadFunctionsMap(GLen
                     return LUMINANCE_to_default;
             }
         }
         case GL_LUMINANCE16F_EXT:
             return LUMINANCE16F_EXT_to_default;
         case GL_LUMINANCE32F_EXT:
             return LUMINANCE32F_EXT_to_default;
         case GL_LUMINANCE8_ALPHA8_EXT:
-            return LUMINANCE8_ALPHA8_EXT_to_default;
+        {
+            switch (angleFormat)
+            {
+                case Format::ID::R8G8B8A8_UNORM:
+                    return LUMINANCE8_ALPHA8_EXT_to_R8G8B8A8_UNORM;
+                case Format::ID::R8G8_UNORM:
+                    return LUMINANCE8_ALPHA8_EXT_to_R8G8_UNORM;
+                default:
+                    break;
+            }
+            break;
+        }
         case GL_LUMINANCE8_EXT:
-            return LUMINANCE8_EXT_to_default;
+        {
+            switch (angleFormat)
+            {
+                case Format::ID::R8G8B8A8_UNORM:
+                    return LUMINANCE8_EXT_to_R8G8B8A8_UNORM;
+                case Format::ID::R8_UNORM:
+                    return LUMINANCE8_EXT_to_R8_UNORM;
+                default:
+                    break;
+            }
+            break;
+        }
         case GL_LUMINANCE_ALPHA:
         {
             switch (angleFormat)
             {
                 case Format::ID::R16G16B16A16_FLOAT:
                     return LUMINANCE_ALPHA_to_R16G16B16A16_FLOAT;
                 case Format::ID::R32G32B32A32_FLOAT:
                     return LUMINANCE_ALPHA_to_R32G32B32A32_FLOAT;
@@ -2274,27 +2358,31 @@ LoadFunctionMap GetLoadFunctionsMap(GLen
             break;
         }
         case GL_RGB565:
         {
             switch (angleFormat)
             {
                 case Format::ID::B5G6R5_UNORM:
                     return RGB565_to_B5G6R5_UNORM;
+                case Format::ID::R5G6B5_UNORM:
+                    return RGB565_to_R5G6B5_UNORM;
                 case Format::ID::R8G8B8A8_UNORM:
                     return RGB565_to_R8G8B8A8_UNORM;
                 default:
                     break;
             }
             break;
         }
         case GL_RGB5_A1:
         {
             switch (angleFormat)
             {
+                case Format::ID::A1R5G5B5_UNORM:
+                    return RGB5_A1_to_A1R5G5B5_UNORM;
                 case Format::ID::B5G5R5A1_UNORM:
                     return RGB5_A1_to_B5G5R5A1_UNORM;
                 case Format::ID::R8G8B8A8_UNORM:
                     return RGB5_A1_to_R8G8B8A8_UNORM;
                 default:
                     break;
             }
             break;
--- a/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.cpp
+++ b/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.cpp
@@ -472,76 +472,76 @@ IncompleteTextureSet::~IncompleteTexture
 {
 }
 
 void IncompleteTextureSet::onDestroy(const gl::Context *context)
 {
     // Clear incomplete textures.
     for (auto &incompleteTexture : mIncompleteTextures)
     {
-        ANGLE_SWALLOW_ERR(incompleteTexture.second->onDestroy(context));
-        incompleteTexture.second.set(context, nullptr);
+        if (incompleteTexture.get() != nullptr)
+        {
+            ANGLE_SWALLOW_ERR(incompleteTexture->onDestroy(context));
+            incompleteTexture.set(context, nullptr);
+        }
     }
-    mIncompleteTextures.clear();
 }
 
 gl::Error IncompleteTextureSet::getIncompleteTexture(
     const gl::Context *context,
-    GLenum type,
+    gl::TextureType type,
     MultisampleTextureInitializer *multisampleInitializer,
     gl::Texture **textureOut)
 {
-    auto iter = mIncompleteTextures.find(type);
-    if (iter != mIncompleteTextures.end())
+    *textureOut = mIncompleteTextures[type].get();
+    if (*textureOut != nullptr)
     {
-        *textureOut = iter->second.get();
         return gl::NoError();
     }
 
     ContextImpl *implFactory = context->getImplementation();
 
     const GLubyte color[] = {0, 0, 0, 255};
     const gl::Extents colorSize(1, 1, 1);
     gl::PixelUnpackState unpack;
     unpack.alignment = 1;
     const gl::Box area(0, 0, 0, 1, 1, 1);
 
     // If a texture is external use a 2D texture for the incomplete texture
-    GLenum createType = (type == GL_TEXTURE_EXTERNAL_OES) ? GL_TEXTURE_2D : type;
+    gl::TextureType createType = (type == gl::TextureType::External) ? gl::TextureType::_2D : type;
 
     gl::Texture *tex = new gl::Texture(implFactory, std::numeric_limits<GLuint>::max(), createType);
     angle::UniqueObjectPointer<gl::Texture, gl::Context> t(tex, context);
 
-    if (createType == GL_TEXTURE_2D_MULTISAMPLE)
+    if (createType == gl::TextureType::_2DMultisample)
     {
         ANGLE_TRY(t->setStorageMultisample(context, createType, 1, GL_RGBA8, colorSize, true));
     }
     else
     {
         ANGLE_TRY(t->setStorage(context, createType, 1, GL_RGBA8, colorSize));
     }
 
-    if (type == GL_TEXTURE_CUBE_MAP)
+    if (type == gl::TextureType::CubeMap)
     {
-        for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
-             face++)
+        for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets())
         {
             ANGLE_TRY(
                 t->setSubImage(context, unpack, face, 0, area, GL_RGBA, GL_UNSIGNED_BYTE, color));
         }
     }
-    else if (type == GL_TEXTURE_2D_MULTISAMPLE)
+    else if (type == gl::TextureType::_2DMultisample)
     {
         // Call a specialized clear function to init a multisample texture.
         ANGLE_TRY(multisampleInitializer->initializeMultisampleTextureToBlack(context, t.get()));
     }
     else
     {
-        ANGLE_TRY(
-            t->setSubImage(context, unpack, createType, 0, area, GL_RGBA, GL_UNSIGNED_BYTE, color));
+        ANGLE_TRY(t->setSubImage(context, unpack, gl::NonCubeTextureTypeToTarget(createType), 0,
+                                 area, GL_RGBA, GL_UNSIGNED_BYTE, color));
     }
 
     t->syncState();
 
     mIncompleteTextures[type].set(context, t.release());
     *textureOut = mIncompleteTextures[type].get();
     return gl::NoError();
 }
--- a/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.h
+++ b/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.h
@@ -245,17 +245,17 @@ class IncompleteTextureSet final : angle
 {
   public:
     IncompleteTextureSet();
     ~IncompleteTextureSet();
 
     void onDestroy(const gl::Context *context);
 
     gl::Error getIncompleteTexture(const gl::Context *context,
-                                   GLenum type,
+                                   gl::TextureType type,
                                    MultisampleTextureInitializer *multisampleInitializer,
                                    gl::Texture **textureOut);
 
   private:
     gl::TextureMap mIncompleteTextures;
 };
 
 }  // namespace rx
deleted file mode 100644
--- a/gfx/angle/checkout/src/libANGLE/signal_utils.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-//
-// 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.
-//
-// signal_utils:
-//   Implements the Observer pattern for sending state change notifications
-//   from Subject objects to dependent Observer objects.
-//
-//   See design document:
-//   https://docs.google.com/document/d/15Edfotqg6_l1skTEL8ADQudF_oIdNa7i8Po43k6jMd4/
-
-#include "libANGLE/signal_utils.h"
-
-#include <algorithm>
-
-#include "common/debug.h"
-
-namespace angle
-{
-// Observer implementation.
-ObserverInterface::~ObserverInterface() = default;
-
-// Subject implementation.
-Subject::Subject()
-{
-}
-
-Subject::~Subject()
-{
-    resetObservers();
-}
-
-bool Subject::hasObservers() const
-{
-    return !mObservers.empty();
-}
-
-void Subject::addObserver(ObserverBinding *observer)
-{
-    ASSERT(std::find(mObservers.begin(), mObservers.end(), observer) == mObservers.end());
-    mObservers.push_back(observer);
-}
-
-void Subject::removeObserver(ObserverBinding *observer)
-{
-    auto iter = std::find(mObservers.begin(), mObservers.end(), observer);
-    ASSERT(iter != mObservers.end());
-    mObservers.erase(iter);
-}
-
-void Subject::onStateChange(const gl::Context *context, SubjectMessage message) const
-{
-    if (mObservers.empty())
-        return;
-
-    for (const angle::ObserverBinding *receiver : mObservers)
-    {
-        receiver->onStateChange(context, message);
-    }
-}
-
-void Subject::resetObservers()
-{
-    for (angle::ObserverBinding *observer : mObservers)
-    {
-        observer->onSubjectReset();
-    }
-    mObservers.clear();
-}
-
-// ObserverBinding implementation.
-ObserverBinding::ObserverBinding(ObserverInterface *observer, SubjectIndex index)
-    : mSubject(nullptr), mObserver(observer), mIndex(index)
-{
-    ASSERT(observer);
-}
-
-ObserverBinding::~ObserverBinding()
-{
-    reset();
-}
-
-ObserverBinding::ObserverBinding(const ObserverBinding &other) = default;
-
-ObserverBinding &ObserverBinding::operator=(const ObserverBinding &other) = default;
-
-void ObserverBinding::bind(Subject *subject)
-{
-    ASSERT(mObserver);
-    if (mSubject)
-    {
-        mSubject->removeObserver(this);
-    }
-
-    mSubject = subject;
-
-    if (mSubject)
-    {
-        mSubject->addObserver(this);
-    }
-}
-
-void ObserverBinding::reset()
-{
-    bind(nullptr);
-}
-
-void ObserverBinding::onStateChange(const gl::Context *context, SubjectMessage message) const
-{
-    mObserver->onSubjectStateChange(context, mIndex, message);
-}
-
-void ObserverBinding::onSubjectReset()
-{
-    mSubject = nullptr;
-}
-}  // namespace angle
deleted file mode 100644
--- a/gfx/angle/checkout/src/libANGLE/signal_utils.h
+++ /dev/null
@@ -1,87 +0,0 @@
-//
-// 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.
-//
-// signal_utils:
-//   Implements the Observer pattern for sending state change notifications
-//   from Subject objects to dependent Observer objects.
-//
-//   See design document:
-//   https://docs.google.com/document/d/15Edfotqg6_l1skTEL8ADQudF_oIdNa7i8Po43k6jMd4/
-
-#ifndef LIBANGLE_SIGNAL_UTILS_H_
-#define LIBANGLE_SIGNAL_UTILS_H_
-
-#include "common/angleutils.h"
-
-namespace gl
-{
-class Context;
-}  // namespace gl
-
-namespace angle
-{
-
-using SubjectIndex = size_t;
-
-enum class SubjectMessage
-{
-    STATE_CHANGE,
-};
-
-// The observing class inherits from this interface class.
-class ObserverInterface
-{
-  public:
-    virtual ~ObserverInterface();
-    virtual void onSubjectStateChange(const gl::Context *context,
-                                      SubjectIndex index,
-                                      SubjectMessage message) = 0;
-};
-
-class ObserverBinding;
-
-// Maintains a list of observer bindings. Sends update messages to the observer.
-class Subject : NonCopyable
-{
-  public:
-    Subject();
-    virtual ~Subject();
-
-    void onStateChange(const gl::Context *context, SubjectMessage message) const;
-    bool hasObservers() const;
-    void resetObservers();
-
-  private:
-    // Only the ObserverBinding class should add or remove observers.
-    friend class ObserverBinding;
-    void addObserver(ObserverBinding *observer);
-    void removeObserver(ObserverBinding *observer);
-
-    std::vector<ObserverBinding *> mObservers;
-};
-
-// Keeps a binding between a Subject and Observer, with a specific subject index.
-class ObserverBinding final
-{
-  public:
-    ObserverBinding(ObserverInterface *observer, SubjectIndex index);
-    ~ObserverBinding();
-    ObserverBinding(const ObserverBinding &other);
-    ObserverBinding &operator=(const ObserverBinding &other);
-
-    void bind(Subject *subject);
-    void reset();
-    void onStateChange(const gl::Context *context, SubjectMessage message) const;
-    void onSubjectReset();
-
-  private:
-    Subject *mSubject;
-    ObserverInterface *mObserver;
-    SubjectIndex mIndex;
-};
-
-}  // namespace angle
-
-#endif  // LIBANGLE_SIGNAL_UTILS_H_
--- a/gfx/angle/checkout/src/libANGLE/validationEGL.cpp
+++ b/gfx/angle/checkout/src/libANGLE/validationEGL.cpp
@@ -20,77 +20,77 @@
 #include "libANGLE/formatutils.h"
 
 #include <EGL/eglext.h>
 
 namespace egl
 {
 namespace
 {
-size_t GetMaximumMipLevel(const gl::Context *context, GLenum target)
+size_t GetMaximumMipLevel(const gl::Context *context, gl::TextureType type)
 {
     const gl::Caps &caps = context->getCaps();
 
     size_t maxDimension = 0;
-    switch (target)
+    switch (type)
     {
-        case GL_TEXTURE_2D:
+        case gl::TextureType::_2D:
+        case gl::TextureType::_2DArray:
+        case gl::TextureType::_2DMultisample:
             maxDimension = caps.max2DTextureSize;
             break;
-        case GL_TEXTURE_RECTANGLE_ANGLE:
+        case gl::TextureType::Rectangle:
             maxDimension = caps.maxRectangleTextureSize;
             break;
-        case GL_TEXTURE_CUBE_MAP:
+        case gl::TextureType::CubeMap:
             maxDimension = caps.maxCubeMapTextureSize;
             break;
-        case GL_TEXTURE_3D:
+        case gl::TextureType::_3D:
             maxDimension = caps.max3DTextureSize;
             break;
-        case GL_TEXTURE_2D_ARRAY:
-            maxDimension = caps.max2DTextureSize;
-            break;
+
         default:
             UNREACHABLE();
     }
 
     return gl::log2(static_cast<int>(maxDimension));
 }
 
 bool TextureHasNonZeroMipLevelsSpecified(const gl::Context *context, const gl::Texture *texture)
 {
-    size_t maxMip = GetMaximumMipLevel(context, texture->getTarget());
+    size_t maxMip = GetMaximumMipLevel(context, texture->getType());
     for (size_t level = 1; level < maxMip; level++)
     {
-        if (texture->getTarget() == GL_TEXTURE_CUBE_MAP)
+        if (texture->getType() == gl::TextureType::CubeMap)
         {
-            for (GLenum face = gl::FirstCubeMapTextureTarget; face <= gl::LastCubeMapTextureTarget;
-                 face++)
+            for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets())
             {
                 if (texture->getFormat(face, level).valid())
                 {
                     return true;
                 }
             }
         }
         else
         {
-            if (texture->getFormat(texture->getTarget(), level).valid())
+            if (texture->getFormat(gl::NonCubeTextureTypeToTarget(texture->getType()), level)
+                    .valid())
             {
                 return true;
             }
         }
     }
 
     return false;
 }
 
 bool CubeTextureHasUnspecifiedLevel0Face(const gl::Texture *texture)
 {
-    ASSERT(texture->getTarget() == GL_TEXTURE_CUBE_MAP);
-    for (GLenum face = gl::FirstCubeMapTextureTarget; face <= gl::LastCubeMapTextureTarget; face++)
+    ASSERT(texture->getType() == gl::TextureType::CubeMap);
+    for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets())
     {
         if (!texture->getFormat(face, 0).valid())
         {
             return true;
         }
     }
 
     return false;
@@ -733,16 +733,30 @@ Error ValidateCreateContext(Display *dis
               }
               if (value != EGL_TRUE && value != EGL_FALSE)
               {
                   return EglBadAttribute() << "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be "
                                               "either EGL_TRUE or EGL_FALSE.";
               }
               break;
 
+          case EGL_EXTENSIONS_ENABLED_ANGLE:
+              if (!display->getExtensions().createContextExtensionsEnabled)
+              {
+                  return EglBadAttribute()
+                         << "Attribute EGL_EXTENSIONS_ENABLED_ANGLE "
+                            "requires EGL_ANGLE_create_context_extensions_enabled.";
+              }
+              if (value != EGL_TRUE && value != EGL_FALSE)
+              {
+                  return EglBadAttribute() << "EGL_EXTENSIONS_ENABLED_ANGLE must be "
+                                              "either EGL_TRUE or EGL_FALSE.";
+              }
+              break;
+
           default:
               return EglBadAttribute() << "Unknown attribute.";
         }
     }
 
     switch (clientMajorVersion)
     {
         case 1:
@@ -1474,29 +1488,29 @@ Error ValidateCreateImageKHR(const Displ
 
             if (buffer == 0)
             {
                 return EglBadParameter() << "buffer cannot reference a 2D texture with the name 0.";
             }
 
             const gl::Texture *texture =
                 context->getTexture(egl_gl::EGLClientBufferToGLObjectHandle(buffer));
-            if (texture == nullptr || texture->getTarget() != GL_TEXTURE_2D)
+            if (texture == nullptr || texture->getType() != gl::TextureType::_2D)
             {
                 return EglBadParameter() << "target is not a 2D texture.";
             }
 
             if (texture->getBoundSurface() != nullptr)
             {
                 return EglBadAccess() << "texture has a surface bound to it.";
             }
 
             EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL_KHR, 0);
-            if (texture->getWidth(GL_TEXTURE_2D, static_cast<size_t>(level)) == 0 ||
-                texture->getHeight(GL_TEXTURE_2D, static_cast<size_t>(level)) == 0)
+            if (texture->getWidth(gl::TextureTarget::_2D, static_cast<size_t>(level)) == 0 ||
+                texture->getHeight(gl::TextureTarget::_2D, static_cast<size_t>(level)) == 0)
             {
                 return EglBadParameter()
                        << "target 2D texture does not have a valid size at specified level.";
             }
 
             ANGLE_TRY(ValidateCreateImageKHRMipLevelCommon(context, texture, level));
         }
         break;
@@ -1516,28 +1530,28 @@ Error ValidateCreateImageKHR(const Displ
             if (buffer == 0)
             {
                 return EglBadParameter()
                        << "buffer cannot reference a cubemap texture with the name 0.";
             }
 
             const gl::Texture *texture =
                 context->getTexture(egl_gl::EGLClientBufferToGLObjectHandle(buffer));
-            if (texture == nullptr || texture->getTarget() != GL_TEXTURE_CUBE_MAP)
+            if (texture == nullptr || texture->getType() != gl::TextureType::CubeMap)
             {
                 return EglBadParameter() << "target is not a cubemap texture.";
             }
 
             if (texture->getBoundSurface() != nullptr)
             {
                 return EglBadAccess() << "texture has a surface bound to it.";
             }
 
             EGLAttrib level    = attributes.get(EGL_GL_TEXTURE_LEVEL_KHR, 0);
-            GLenum cubeMapFace = egl_gl::EGLCubeMapTargetToGLCubeMapTarget(target);
+            gl::TextureTarget cubeMapFace = egl_gl::EGLCubeMapTargetToCubeMapTarget(target);
             if (texture->getWidth(cubeMapFace, static_cast<size_t>(level)) == 0 ||
                 texture->getHeight(cubeMapFace, static_cast<size_t>(level)) == 0)
             {
                 return EglBadParameter() << "target cubemap texture does not have a valid "
                                             "size at specified level and face.";
             }
 
             ANGLE_TRY(ValidateCreateImageKHRMipLevelCommon(context, texture, level));
@@ -1561,38 +1575,38 @@ Error ValidateCreateImageKHR(const Displ
 
             if (buffer == 0)
             {
                 return EglBadParameter() << "buffer cannot reference a 3D texture with the name 0.";
             }
 
             const gl::Texture *texture =
                 context->getTexture(egl_gl::EGLClientBufferToGLObjectHandle(buffer));
-            if (texture == nullptr || texture->getTarget() != GL_TEXTURE_3D)
+            if (texture == nullptr || texture->getType() != gl::TextureType::_3D)
             {
                 return EglBadParameter() << "target is not a 3D texture.";
             }
 
             if (texture->getBoundSurface() != nullptr)
             {
                 return EglBadAccess() << "texture has a surface bound to it.";
             }
 
             EGLAttrib level   = attributes.get(EGL_GL_TEXTURE_LEVEL_KHR, 0);
             EGLAttrib zOffset = attributes.get(EGL_GL_TEXTURE_ZOFFSET_KHR, 0);
-            if (texture->getWidth(GL_TEXTURE_3D, static_cast<size_t>(level)) == 0 ||
-                texture->getHeight(GL_TEXTURE_3D, static_cast<size_t>(level)) == 0 ||
-                texture->getDepth(GL_TEXTURE_3D, static_cast<size_t>(level)) == 0)
+            if (texture->getWidth(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0 ||
+                texture->getHeight(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0 ||
+                texture->getDepth(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0)
             {
                 return EglBadParameter()
                        << "target 3D texture does not have a valid size at specified level.";
             }
 
             if (static_cast<size_t>(zOffset) >=
-                texture->getDepth(GL_TEXTURE_3D, static_cast<size_t>(level)))
+                texture->getDepth(gl::TextureTarget::_3D, static_cast<size_t>(level)))
             {
                 return EglBadParameter() << "target 3D texture does not have enough layers "
                                             "for the specified Z offset at the specified "
                                             "level.";
             }
 
             ANGLE_TRY(ValidateCreateImageKHRMipLevelCommon(context, texture, level));
         }
@@ -1816,17 +1830,17 @@ Error ValidateStreamConsumerGLTextureExt
     }
 
     if (stream->getState() != EGL_STREAM_STATE_CREATED_KHR)
     {
         return EglBadState() << "Invalid stream state";
     }
 
     // Lookup the texture and ensure it is correct
-    gl::Texture *texture = context->getGLState().getTargetTexture(GL_TEXTURE_EXTERNAL_OES);
+    gl::Texture *texture = context->getGLState().getTargetTexture(gl::TextureType::External);
     if (texture == nullptr || texture->getId() == 0)
     {
         return EglBadAccess() << "No external texture bound";
     }
 
     return NoError();
 }
 
@@ -2021,17 +2035,17 @@ Error ValidateStreamConsumerGLTextureExt
         {
             if (plane[i] != -1)
             {
                 return EglBadMatch() << "Planes cannot be specified";
             }
         }
 
         // Lookup the texture and ensure it is correct
-        gl::Texture *texture = context->getGLState().getTargetTexture(GL_TEXTURE_EXTERNAL_OES);
+        gl::Texture *texture = context->getGLState().getTargetTexture(gl::TextureType::External);
         if (texture == nullptr || texture->getId() == 0)
         {
             return EglBadAccess() << "No external texture bound";
         }
     }
     else
     {
         if (planeCount == -1)
@@ -2056,17 +2070,17 @@ Error ValidateStreamConsumerGLTextureExt
         {
             if (plane[i] == -1)
             {
                 return EglBadMatch() << "Not all planes specified";
             }
             if (plane[i] != EGL_NONE)
             {
                 gl::Texture *texture = context->getGLState().getSamplerTexture(
-                    static_cast<unsigned int>(plane[i]), GL_TEXTURE_EXTERNAL_OES);
+                    static_cast<unsigned int>(plane[i]), gl::TextureType::External);
                 if (texture == nullptr || texture->getId() == 0)
                 {
                     return EglBadAccess()
                            << "No external texture bound at one or more specified texture units";
                 }
                 if (textureSet.find(texture) != textureSet.end())
                 {
                     return EglBadAccess() << "Multiple planes bound to same texture object";
--- a/gfx/angle/checkout/src/libANGLE/validationES.cpp
+++ b/gfx/angle/checkout/src/libANGLE/validationES.cpp
@@ -14,16 +14,17 @@
 #include "libANGLE/Framebuffer.h"
 #include "libANGLE/FramebufferAttachment.h"
 #include "libANGLE/Image.h"
 #include "libANGLE/Program.h"
 #include "libANGLE/Query.h"
 #include "libANGLE/Texture.h"
 #include "libANGLE/TransformFeedback.h"
 #include "libANGLE/VertexArray.h"
+#include "libANGLE/angletypes.h"
 #include "libANGLE/formatutils.h"
 #include "libANGLE/queryconversions.h"
 #include "libANGLE/validationES2.h"
 #include "libANGLE/validationES3.h"
 
 #include "common/mathutil.h"
 #include "common/utilities.h"
 
@@ -62,20 +63,17 @@ bool CompressedTextureFormatRequiresExac
 }
 bool CompressedSubTextureFormatRequiresExactSize(GLenum internalFormat)
 {
     // Compressed sub textures have additional formats that requires exact size.
     // ES 3.1, Section 8.7, Page 171
     return CompressedTextureFormatRequiresExactSize(internalFormat) ||
            IsETC2EACFormat(internalFormat);
 }
-bool ValidateDrawAttribs(ValidationContext *context,
-                         GLint primcount,
-                         GLint maxVertex,
-                         GLint vertexCount)
+bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex, GLint vertexCount)
 {
     const gl::State &state     = context->getGLState();
     const gl::Program *program = state.getProgram();
 
     bool webglCompatibility = context->getExtensions().webglCompatibility;
 
     const VertexArray *vao     = state.getVertexArray();
     const auto &vertexAttribs  = vao->getVertexAttributes();
@@ -87,18 +85,18 @@ bool ValidateDrawAttribs(ValidationConte
         // No need to range check for disabled attribs.
         if (!attrib.enabled)
         {
             continue;
         }
 
         // If we have no buffer, then we either get an error, or there are no more checks to be
         // done.
-        const VertexBinding &binding  = vertexBindings[attrib.bindingIndex];
-        gl::Buffer *buffer            = binding.getBuffer().get();
+        const VertexBinding &binding = vertexBindings[attrib.bindingIndex];
+        gl::Buffer *buffer           = binding.getBuffer().get();
         if (!buffer)
         {
             if (webglCompatibility || !state.areClientArraysEnabled())
             {
                 // [WebGL 1.0] Section 6.5 Enabled Vertex Attributes and Range Checking
                 // If a vertex attribute is enabled as an array via enableVertexAttribArray but
                 // no buffer is bound to that attribute via bindBuffer and vertexAttribPointer,
                 // then calls to drawArrays or drawElements will generate an INVALID_OPERATION
@@ -173,22 +171,29 @@ bool ValidateDrawAttribs(ValidationConte
         // [OpenGL ES 3.0.2] section 2.9.4 page 40:
         // We can return INVALID_OPERATION if our vertex attribute does not have
         // enough backing data.
         if (attribDataSizeWithOffset > static_cast<uint64_t>(buffer->getSize()))
         {
             ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientVertexBufferSize);
             return false;
         }
+
+        if (webglCompatibility && buffer->isBoundForTransformFeedbackAndOtherUse())
+        {
+            ANGLE_VALIDATION_ERR(context, InvalidOperation(),
+                                 VertexBufferBoundForTransformFeedback);
+            return false;
+        }
     }
 
     return true;
 }
 
-bool ValidReadPixelsTypeEnum(ValidationContext *context, GLenum type)
+bool ValidReadPixelsTypeEnum(Context *context, GLenum type)
 {
     switch (type)
     {
         // Types referenced in Table 3.4 of the ES 2.0.25 spec
         case GL_UNSIGNED_BYTE:
         case GL_UNSIGNED_SHORT_4_4_4_4:
         case GL_UNSIGNED_SHORT_5_5_5_1:
         case GL_UNSIGNED_SHORT_5_6_5:
@@ -219,17 +224,17 @@ bool ValidReadPixelsTypeEnum(ValidationC
         case GL_HALF_FLOAT_OES:
             return context->getExtensions().colorBufferHalfFloat;
 
         default:
             return false;
     }
 }
 
-bool ValidReadPixelsFormatEnum(ValidationContext *context, GLenum format)
+bool ValidReadPixelsFormatEnum(Context *context, GLenum format)
 {
     switch (format)
     {
         // Formats referenced in Table 3.4 of the ES 2.0.25 spec (Except luminance)
         case GL_RGBA:
         case GL_RGB:
         case GL_ALPHA:
             return context->getClientVersion() >= ES_2_0;
@@ -250,17 +255,17 @@ bool ValidReadPixelsFormatEnum(Validatio
         case GL_BGRA_EXT:
             return context->getExtensions().readFormatBGRA;
 
         default:
             return false;
     }
 }
 
-bool ValidReadPixelsFormatType(ValidationContext *context,
+bool ValidReadPixelsFormatType(Context *context,
                                GLenum framebufferComponentType,
                                GLenum format,
                                GLenum type)
 {
     switch (framebufferComponentType)
     {
         case GL_UNSIGNED_NORMALIZED:
             // TODO(geofflang): Don't accept BGRA here.  Some chrome internals appear to try to use
@@ -448,36 +453,36 @@ bool ValidateTextureMaxAnisotropyValue(C
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), OutsideOfBounds);
         return false;
     }
 
     return true;
 }
 
-bool ValidateFragmentShaderColorBufferTypeMatch(ValidationContext *context)
+bool ValidateFragmentShaderColorBufferTypeMatch(Context *context)
 {
     const Program *program         = context->getGLState().getProgram();
     const Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
 
     if (!ComponentTypeMask::Validate(program->getDrawBufferTypeMask().to_ulong(),
                                      framebuffer->getDrawBufferTypeMask().to_ulong(),
                                      program->getActiveOutputVariables().to_ulong(),
                                      framebuffer->getDrawBufferMask().to_ulong()))
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), DrawBufferTypeMismatch);
         return false;
     }
 
     return true;
 }
 
-bool ValidateVertexShaderAttributeTypeMatch(ValidationContext *context)
-{
-    const auto &glState       = context->getGLState();
+bool ValidateVertexShaderAttributeTypeMatch(Context *context)
+{
+    const auto &glState    = context->getGLState();
     const Program *program = context->getGLState().getProgram();
     const VertexArray *vao = context->getGLState().getVertexArray();
 
     unsigned long stateCurrentValuesTypeBits = glState.getCurrentValuesTypeMask().to_ulong();
     unsigned long vaoAttribTypeBits          = vao->getAttributesTypeMask().to_ulong();
     unsigned long vaoAttribEnabledMask       = vao->getAttributesMask().to_ulong();
 
     vaoAttribEnabledMask |= vaoAttribEnabledMask << MAX_COMPONENT_TYPE_MASK_INDEX;
@@ -488,18 +493,50 @@ bool ValidateVertexShaderAttributeTypeMa
                                      program->getAttributesMask().to_ulong(), 0xFFFF))
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), VertexShaderTypeMismatch);
         return false;
     }
     return true;
 }
 
+bool IsCompatibleDrawModeWithGeometryShader(GLenum drawMode,
+                                            GLenum geometryShaderInputPrimitiveType)
+{
+    // [EXT_geometry_shader] Section 11.1gs.1, Geometry Shader Input Primitives
+    switch (geometryShaderInputPrimitiveType)
+    {
+        case GL_POINTS:
+            return drawMode == GL_POINTS;
+        case GL_LINES:
+            return drawMode == GL_LINES || drawMode == GL_LINE_STRIP || drawMode == GL_LINE_LOOP;
+        case GL_LINES_ADJACENCY_EXT:
+            return drawMode == GL_LINES_ADJACENCY_EXT || drawMode == GL_LINE_STRIP_ADJACENCY_EXT;
+        case GL_TRIANGLES:
+            return drawMode == GL_TRIANGLES || drawMode == GL_TRIANGLE_FAN ||
+                   drawMode == GL_TRIANGLE_STRIP;
+        case GL_TRIANGLES_ADJACENCY_EXT:
+            return drawMode == GL_TRIANGLES_ADJACENCY_EXT ||
+                   drawMode == GL_TRIANGLE_STRIP_ADJACENCY_EXT;
+        default:
+            UNREACHABLE();
+            return false;
+    }
+}
+
 }  // anonymous namespace
 
+void SetRobustLengthParam(GLsizei *length, GLsizei value)
+{
+    if (length)
+    {
+        *length = value;
+    }
+}
+
 bool IsETC2EACFormat(const GLenum format)
 {
     // ES 3.1, Table 8.19
     switch (format)
     {
         case GL_COMPRESSED_R11_EAC:
         case GL_COMPRESSED_SIGNED_R11_EAC:
         case GL_COMPRESSED_RG11_EAC:
@@ -512,101 +549,101 @@ bool IsETC2EACFormat(const GLenum format
         case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
             return true;
 
         default:
             return false;
     }
 }
 
-bool ValidTextureTarget(const ValidationContext *context, GLenum target)
-{
-    switch (target)
-    {
-        case GL_TEXTURE_2D:
-        case GL_TEXTURE_CUBE_MAP:
+bool ValidTextureTarget(const Context *context, TextureType type)
+{
+    switch (type)
+    {
+        case TextureType::_2D:
+        case TextureType::CubeMap:
             return true;
 
-        case GL_TEXTURE_RECTANGLE_ANGLE:
+        case TextureType::Rectangle:
             return context->getExtensions().textureRectangle;
 
-        case GL_TEXTURE_3D:
-        case GL_TEXTURE_2D_ARRAY:
+        case TextureType::_3D:
+        case TextureType::_2DArray:
             return (context->getClientMajorVersion() >= 3);
 
-        case GL_TEXTURE_2D_MULTISAMPLE:
+        case TextureType::_2DMultisample:
             return (context->getClientVersion() >= Version(3, 1));
 
         default:
             return false;
     }
 }
 
-bool ValidTexture2DTarget(const ValidationContext *context, GLenum target)
-{
-    switch (target)
-    {
-        case GL_TEXTURE_2D:
-        case GL_TEXTURE_CUBE_MAP:
+bool ValidTexture2DTarget(const Context *context, TextureType type)
+{
+    switch (type)
+    {
+        case TextureType::_2D:
+        case TextureType::CubeMap:
             return true;
 
-        case GL_TEXTURE_RECTANGLE_ANGLE:
+        case TextureType::Rectangle:
             return context->getExtensions().textureRectangle;
 
         default:
             return false;
     }
 }
 
-bool ValidTexture3DTarget(const ValidationContext *context, GLenum target)
+bool ValidTexture3DTarget(const Context *context, TextureType target)
 {
     switch (target)
     {
-        case GL_TEXTURE_3D:
-        case GL_TEXTURE_2D_ARRAY:
+        case TextureType::_3D:
+        case TextureType::_2DArray:
             return (context->getClientMajorVersion() >= 3);
 
         default:
             return false;
     }
 }
 
 // Most texture GL calls are not compatible with external textures, so we have a separate validation
 // function for use in the GL calls that do
-bool ValidTextureExternalTarget(const ValidationContext *context, GLenum target)
-{
-    return (target == GL_TEXTURE_EXTERNAL_OES) &&
+bool ValidTextureExternalTarget(const Context *context, TextureType target)
+{
+    return (target == TextureType::External) &&
            (context->getExtensions().eglImageExternal ||
             context->getExtensions().eglStreamConsumerExternal);
 }
 
 // This function differs from ValidTextureTarget in that the target must be
 // usable as the destination of a 2D operation-- so a cube face is valid, but
 // GL_TEXTURE_CUBE_MAP is not.
 // Note: duplicate of IsInternalTextureTarget
-bool ValidTexture2DDestinationTarget(const ValidationContext *context, GLenum target)
+bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget target)
 {
     switch (target)
     {
-        case GL_TEXTURE_2D:
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+        case TextureTarget::_2D:
+        case TextureTarget::CubeMapNegativeX:
+        case TextureTarget::CubeMapNegativeY:
+        case TextureTarget::CubeMapNegativeZ:
+        case TextureTarget::CubeMapPositiveX:
+        case TextureTarget::CubeMapPositiveY:
+        case TextureTarget::CubeMapPositiveZ:
             return true;
-        case GL_TEXTURE_RECTANGLE_ANGLE:
+        case TextureTarget::Rectangle:
             return context->getExtensions().textureRectangle;
         default:
             return false;
     }
 }
 
-bool ValidateDrawElementsInstancedBase(ValidationContext *context,
+bool ValidateDrawElementsInstancedBase(Context *context,
                                        GLenum mode,
                                        GLsizei count,
                                        GLenum type,
                                        const GLvoid *indices,
                                        GLsizei primcount)
 {
     if (primcount < 0)
     {
@@ -637,17 +674,17 @@ bool ValidateDrawArraysInstancedBase(Con
     if (!ValidateDrawArraysCommon(context, mode, first, count, primcount))
     {
         return false;
     }
 
     return true;
 }
 
-bool ValidateDrawInstancedANGLE(ValidationContext *context)
+bool ValidateDrawInstancedANGLE(Context *context)
 {
     // Verify there is at least one active attribute with a divisor of zero
     const State &state = context->getGLState();
 
     Program *program = state.getProgram();
 
     const auto &attribs  = state.getVertexArray()->getVertexAttributes();
     const auto &bindings = state.getVertexArray()->getVertexBindings();
@@ -660,51 +697,46 @@ bool ValidateDrawInstancedANGLE(Validati
             return true;
         }
     }
 
     ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoZeroDivisor);
     return false;
 }
 
-bool ValidTexture3DDestinationTarget(const ValidationContext *context, GLenum target)
+bool ValidTexture3DDestinationTarget(const Context *context, TextureType target)
 {
     switch (target)
     {
-        case GL_TEXTURE_3D:
-        case GL_TEXTURE_2D_ARRAY:
+        case TextureType::_3D:
+        case TextureType::_2DArray:
             return true;
         default:
             return false;
     }
 }
 
-bool ValidTexLevelDestinationTarget(const ValidationContext *context, GLenum target)
-{
-    switch (target)
-    {
-        case GL_TEXTURE_2D:
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-        case GL_TEXTURE_3D:
-        case GL_TEXTURE_2D_ARRAY:
-        case GL_TEXTURE_2D_MULTISAMPLE:
+bool ValidTexLevelDestinationTarget(const Context *context, TextureType type)
+{
+    switch (type)
+    {
+        case TextureType::_2D:
+        case TextureType::_2DArray:
+        case TextureType::_2DMultisample:
+        case TextureType::CubeMap:
+        case TextureType::_3D:
             return true;
-        case GL_TEXTURE_RECTANGLE_ANGLE:
+        case TextureType::Rectangle:
             return context->getExtensions().textureRectangle;
         default:
             return false;
     }
 }
 
-bool ValidFramebufferTarget(const ValidationContext *context, GLenum target)
+bool ValidFramebufferTarget(const Context *context, GLenum target)
 {
     static_assert(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER &&
                       GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER,
                   "ANGLE framebuffer enums must equal the ES3 framebuffer enums.");
 
     switch (target)
     {
         case GL_FRAMEBUFFER:
@@ -715,54 +747,44 @@ bool ValidFramebufferTarget(const Valida
             return (context->getExtensions().framebufferBlit ||
                     context->getClientMajorVersion() >= 3);
 
         default:
             return false;
     }
 }
 
-bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level)
+bool ValidMipLevel(const Context *context, TextureType type, GLint level)
 {
     const auto &caps    = context->getCaps();
     size_t maxDimension = 0;
-    switch (target)
-    {
-        case GL_TEXTURE_2D:
+    switch (type)
+    {
+        case TextureType::_2D:
+        case TextureType::_2DArray:
+        case TextureType::_2DMultisample:
             maxDimension = caps.max2DTextureSize;
             break;
-        case GL_TEXTURE_CUBE_MAP:
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+        case TextureType::CubeMap:
             maxDimension = caps.maxCubeMapTextureSize;
             break;
-        case GL_TEXTURE_RECTANGLE_ANGLE:
+        case TextureType::Rectangle:
             return level == 0;
-        case GL_TEXTURE_3D:
+        case TextureType::_3D:
             maxDimension = caps.max3DTextureSize;
             break;
-        case GL_TEXTURE_2D_ARRAY:
-            maxDimension = caps.max2DTextureSize;
-            break;
-        case GL_TEXTURE_2D_MULTISAMPLE:
-            maxDimension = caps.max2DTextureSize;
-            break;
         default:
             UNREACHABLE();
     }
 
     return level <= gl::log2(static_cast<int>(maxDimension)) && level >= 0;
 }
 
-bool ValidImageSizeParameters(ValidationContext *context,
-                              GLenum target,
+bool ValidImageSizeParameters(Context *context,
+                              TextureType target,
                               GLint level,
                               GLsizei width,
                               GLsizei height,
                               GLsizei depth,
                               bool isSubImage)
 {
     if (width < 0 || height < 0 || depth < 0)
     {
@@ -790,17 +812,17 @@ bool ValidImageSizeParameters(Validation
 }
 
 bool ValidCompressedDimension(GLsizei size, GLuint blockSize, bool smallerThanBlockSizeAllowed)
 {
     return (smallerThanBlockSizeAllowed && (size > 0) && (blockSize % size == 0)) ||
            (size % blockSize == 0);
 }
 
-bool ValidCompressedImageSize(const ValidationContext *context,
+bool ValidCompressedImageSize(const Context *context,
                               GLenum internalFormat,
                               GLint level,
                               GLsizei width,
                               GLsizei height)
 {
     const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
     if (!formatInfo.compressed)
     {
@@ -826,17 +848,17 @@ bool ValidCompressedImageSize(const Vali
         {
             return false;
         }
     }
 
     return true;
 }
 
-bool ValidCompressedSubImageSize(const ValidationContext *context,
+bool ValidCompressedSubImageSize(const Context *context,
                                  GLenum internalFormat,
                                  GLint xoffset,
                                  GLint yoffset,
                                  GLsizei width,
                                  GLsizei height,
                                  size_t textureWidth,
                                  size_t textureHeight)
 {
@@ -870,18 +892,18 @@ bool ValidCompressedSubImageSize(const V
         {
             return false;
         }
     }
 
     return true;
 }
 
-bool ValidImageDataSize(ValidationContext *context,
-                        GLenum textureTarget,
+bool ValidImageDataSize(Context *context,
+                        TextureType texType,
                         GLsizei width,
                         GLsizei height,
                         GLsizei depth,
                         GLenum format,
                         GLenum type,
                         const void *pixels,
                         GLsizei imageSize)
 {
@@ -895,18 +917,18 @@ bool ValidImageDataSize(ValidationContex
 
     // ...the data would be unpacked from the buffer object such that the memory reads required
     // would exceed the data store size.
     const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format, type);
     ASSERT(formatInfo.internalFormat != GL_NONE);
     const gl::Extents size(width, height, depth);
     const auto &unpack = context->getGLState().getUnpackState();
 
-    bool targetIs3D   = textureTarget == GL_TEXTURE_3D || textureTarget == GL_TEXTURE_2D_ARRAY;
-    auto endByteOrErr = formatInfo.computePackUnpackEndByte(size, unpack, targetIs3D);
+    bool targetIs3D   = texType == TextureType::_3D || texType == TextureType::_2DArray;
+    auto endByteOrErr = formatInfo.computePackUnpackEndByte(type, size, unpack, targetIs3D);
     if (endByteOrErr.isError())
     {
         context->handleError(endByteOrErr.getError());
         return false;
     }
 
     GLuint endByte = endByteOrErr.getResult();
 
@@ -918,16 +940,23 @@ bool ValidImageDataSize(ValidationContex
 
         if (!checkedEndByte.IsValid() ||
             (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelUnpackBuffer->getSize())))
         {
             // Overflow past the end of the buffer
             context->handleError(InvalidOperation());
             return false;
         }
+        if (context->getExtensions().webglCompatibility &&
+            pixelUnpackBuffer->isBoundForTransformFeedbackAndOtherUse())
+        {
+            ANGLE_VALIDATION_ERR(context, InvalidOperation(),
+                                 PixelUnpackBufferBoundForTransformFeedback);
+            return false;
+        }
     }
     else
     {
         ASSERT(imageSize >= 0);
         if (pixels == nullptr && imageSize != 0)
         {
             context->handleError(InvalidOperation()
                                  << "imageSize must be 0 if no texture data is provided.");
@@ -958,22 +987,24 @@ bool ValidQueryType(const Context *conte
             return context->getClientMajorVersion() >= 3 ||
                    context->getExtensions().occlusionQueryBoolean;
         case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
             return (context->getClientMajorVersion() >= 3);
         case GL_TIME_ELAPSED_EXT:
             return context->getExtensions().disjointTimerQuery;
         case GL_COMMANDS_COMPLETED_CHROMIUM:
             return context->getExtensions().syncQuery;
+        case GL_PRIMITIVES_GENERATED_EXT:
+            return context->getExtensions().geometryShader;
         default:
             return false;
     }
 }
 
-bool ValidateWebGLVertexAttribPointer(ValidationContext *context,
+bool ValidateWebGLVertexAttribPointer(Context *context,
                                       GLenum type,
                                       GLboolean normalized,
                                       GLsizei stride,
                                       const void *ptr,
                                       bool pureInteger)
 {
     ASSERT(context->getExtensions().webglCompatibility);
     // WebGL 1.0 [Section 6.11] Vertex Attribute Data Stride
@@ -1007,17 +1038,17 @@ bool ValidateWebGLVertexAttribPointer(Va
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), StrideMustBeMultipleOfType);
         return false;
     }
 
     return true;
 }
 
-Program *GetValidProgram(ValidationContext *context, GLuint id)
+Program *GetValidProgram(Context *context, GLuint id)
 {
     // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will
     // generate the error INVALID_VALUE if the provided name is not the name of either a shader
     // or program object and INVALID_OPERATION if the provided name identifies an object
     // that is not the expected type."
 
     Program *validProgram = context->getProgram(id);
 
@@ -1031,17 +1062,17 @@ Program *GetValidProgram(ValidationConte
         {
             ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
         }
     }
 
     return validProgram;
 }
 
-Shader *GetValidShader(ValidationContext *context, GLuint id)
+Shader *GetValidShader(Context *context, GLuint id)
 {
     // See ValidProgram for spec details.
 
     Shader *validShader = context->getShader(id);
 
     if (!validShader)
     {
         if (context->getProgram(id))
@@ -1097,17 +1128,17 @@ bool ValidateAttachmentTarget(gl::Contex
                 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
                 return false;
         }
     }
 
     return true;
 }
 
-bool ValidateRenderbufferStorageParametersBase(ValidationContext *context,
+bool ValidateRenderbufferStorageParametersBase(Context *context,
                                                GLenum target,
                                                GLsizei samples,
                                                GLenum internalformat,
                                                GLsizei width,
                                                GLsizei height)
 {
     switch (target)
     {
@@ -1244,37 +1275,34 @@ bool ValidateBlitFramebufferParameters(C
     gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
 
     if (!readFramebuffer || !drawFramebuffer)
     {
         context->handleError(InvalidFramebufferOperation());
         return false;
     }
 
-    if (readFramebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
-    {
-        context->handleError(InvalidFramebufferOperation());
-        return false;
-    }
-
-    if (drawFramebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
-    {
-        context->handleError(InvalidFramebufferOperation());
+    if (!ValidateFramebufferComplete(context, readFramebuffer, true))
+    {
+        return false;
+    }
+
+    if (!ValidateFramebufferComplete(context, drawFramebuffer, true))
+    {
         return false;
     }
 
     if (readFramebuffer->id() == drawFramebuffer->id())
     {
         context->handleError(InvalidOperation());
         return false;
     }
 
-    if (drawFramebuffer->getSamples(context) != 0)
-    {
-        context->handleError(InvalidOperation());
+    if (!ValidateFramebufferNotMultisampled(context, drawFramebuffer))
+    {
         return false;
     }
 
     bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
 
     if (mask & GL_COLOR_BUFFER_BIT)
     {
         const gl::FramebufferAttachment *readColorBuffer = readFramebuffer->getReadColorbuffer();
@@ -1300,17 +1328,17 @@ bool ValidateBlitFramebufferParameters(C
                     // 3) If the read buffer is a signed integer format, the draw buffer must be as
                     // well
                     // Changes with EXT_color_buffer_float:
                     // Case 1) is changed to fixed point OR floating point
                     GLenum readComponentType = readFormat.info->componentType;
                     GLenum drawComponentType = drawFormat.info->componentType;
                     bool readFixedPoint      = (readComponentType == GL_UNSIGNED_NORMALIZED ||
                                            readComponentType == GL_SIGNED_NORMALIZED);
-                    bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED ||
+                    bool drawFixedPoint      = (drawComponentType == GL_UNSIGNED_NORMALIZED ||
                                            drawComponentType == GL_SIGNED_NORMALIZED);
 
                     if (extensions.colorBufferFloat)
                     {
                         bool readFixedOrFloat = (readFixedPoint || readComponentType == GL_FLOAT);
                         bool drawFixedOrFloat = (drawFixedPoint || drawComponentType == GL_FLOAT);
 
                         if (readFixedOrFloat != drawFixedOrFloat)
@@ -1458,26 +1486,34 @@ bool ValidateReadPixelsRobustANGLE(Conte
                                    GLsizei *rows,
                                    void *pixels)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, length,
-                                columns, rows, pixels))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
+    GLsizei writeLength  = 0;
+    GLsizei writeColumns = 0;
+    GLsizei writeRows    = 0;
+
+    if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
+                                &writeColumns, &writeRows, pixels))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, writeLength))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, writeLength);
+    SetRobustLengthParam(columns, writeColumns);
+    SetRobustLengthParam(rows, writeRows);
 
     return true;
 }
 
 bool ValidateReadnPixelsEXT(Context *context,
                             GLint x,
                             GLint y,
                             GLsizei width,
@@ -1505,31 +1541,39 @@ bool ValidateReadnPixelsRobustANGLE(Cont
                                     GLenum format,
                                     GLenum type,
                                     GLsizei bufSize,
                                     GLsizei *length,
                                     GLsizei *columns,
                                     GLsizei *rows,
                                     void *data)
 {
+    GLsizei writeLength  = 0;
+    GLsizei writeColumns = 0;
+    GLsizei writeRows    = 0;
+
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, length,
-                                columns, rows, data))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
+    if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
+                                &writeColumns, &writeRows, data))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, writeLength))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, writeLength);
+    SetRobustLengthParam(columns, writeColumns);
+    SetRobustLengthParam(rows, writeRows);
 
     return true;
 }
 
 bool ValidateGenQueriesEXT(gl::Context *context, GLsizei n, GLuint *ids)
 {
     if (!context->getExtensions().occlusionQueryBoolean &&
         !context->getExtensions().disjointTimerQuery)
@@ -1756,25 +1800,29 @@ bool ValidateGetQueryivRobustANGLE(Conte
                                    GLsizei *length,
                                    GLint *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetQueryivBase(context, target, pname, length))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
+    GLsizei numParams = 0;
+
+    if (!ValidateGetQueryivBase(context, target, pname, &numParams))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
 
     return true;
 }
 
 bool ValidateGetQueryObjectValueBase(Context *context, GLuint id, GLenum pname, GLsizei *numParams)
 {
     if (numParams)
     {
@@ -1837,25 +1885,29 @@ bool ValidateGetQueryObjectivRobustANGLE
         return false;
     }
 
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetQueryObjectValueBase(context, id, pname, length))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
+    GLsizei numParams = 0;
+
+    if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
 
     return true;
 }
 
 bool ValidateGetQueryObjectuivEXT(Context *context, GLuint id, GLenum pname, GLuint *params)
 {
     if (!context->getExtensions().disjointTimerQuery &&
         !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
@@ -1880,25 +1932,29 @@ bool ValidateGetQueryObjectuivRobustANGL
         return false;
     }
 
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetQueryObjectValueBase(context, id, pname, length))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
+    GLsizei numParams = 0;
+
+    if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
 
     return true;
 }
 
 bool ValidateGetQueryObjecti64vEXT(Context *context, GLuint id, GLenum pname, GLint64 *params)
 {
     if (!context->getExtensions().disjointTimerQuery)
     {
@@ -1921,25 +1977,29 @@ bool ValidateGetQueryObjecti64vRobustANG
         return false;
     }
 
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetQueryObjectValueBase(context, id, pname, length))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
+    GLsizei numParams = 0;
+
+    if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
 
     return true;
 }
 
 bool ValidateGetQueryObjectui64vEXT(Context *context, GLuint id, GLenum pname, GLuint64 *params)
 {
     if (!context->getExtensions().disjointTimerQuery)
     {
@@ -1962,30 +2022,34 @@ bool ValidateGetQueryObjectui64vRobustAN
         return false;
     }
 
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetQueryObjectValueBase(context, id, pname, length))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
+    GLsizei numParams = 0;
+
+    if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
 
     return true;
 }
 
-bool ValidateUniformCommonBase(ValidationContext *context,
+bool ValidateUniformCommonBase(Context *context,
                                gl::Program *program,
                                GLint location,
                                GLsizei count,
                                const LinkedUniform **uniformOut)
 {
     // TODO(Jiajia): Add image uniform check in future.
     if (count < 0)
     {
@@ -2040,17 +2104,17 @@ bool ValidateUniformCommonBase(Validatio
         context->handleError(InvalidOperation());
         return false;
     }
 
     *uniformOut = &uniform;
     return true;
 }
 
-bool ValidateUniform1ivValue(ValidationContext *context,
+bool ValidateUniform1ivValue(Context *context,
                              GLenum uniformType,
                              GLsizei count,
                              const GLint *value)
 {
     // Value type is GL_INT, because we only get here from glUniform1i{v}.
     // It is compatible with INT or BOOL.
     // Do these cheap tests first, for a little extra speed.
     if (GL_INT == uniformType || GL_BOOL == uniformType)
@@ -2072,61 +2136,58 @@ bool ValidateUniform1ivValue(ValidationC
         }
         return true;
     }
 
     context->handleError(InvalidOperation() << "wrong type of value for uniform");
     return false;
 }
 
-bool ValidateUniformValue(ValidationContext *context, GLenum valueType, GLenum uniformType)
+bool ValidateUniformValue(Context *context, GLenum valueType, GLenum uniformType)
 {
     // Check that the value type is compatible with uniform type.
     // Do the cheaper test first, for a little extra speed.
     if (valueType == uniformType || VariableBoolVectorType(valueType) == uniformType)
     {
         return true;
     }
 
     ANGLE_VALIDATION_ERR(context, InvalidOperation(), UniformSizeMismatch);
     return false;
 }
 
-bool ValidateUniformMatrixValue(ValidationContext *context, GLenum valueType, GLenum uniformType)
+bool ValidateUniformMatrixValue(Context *context, GLenum valueType, GLenum uniformType)
 {
     // Check that the value type is compatible with uniform type.
     if (valueType == uniformType)
     {
         return true;
     }
 
     context->handleError(InvalidOperation() << "wrong type of value for uniform");
     return false;
 }
 
-bool ValidateUniform(ValidationContext *context, GLenum valueType, GLint location, GLsizei count)
+bool ValidateUniform(Context *context, GLenum valueType, GLint location, GLsizei count)
 {
     const LinkedUniform *uniform = nullptr;
     gl::Program *programObject   = context->getGLState().getProgram();
     return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
            ValidateUniformValue(context, valueType, uniform->type);
 }
 
-bool ValidateUniform1iv(ValidationContext *context,
-                        GLint location,
-                        GLsizei count,
-                        const GLint *value)
+bool ValidateUniform1iv(Context *context, GLint location, GLsizei count, const GLint *value)
 {
     const LinkedUniform *uniform = nullptr;
     gl::Program *programObject   = context->getGLState().getProgram();
     return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
            ValidateUniform1ivValue(context, uniform->type, count, value);
 }
 
-bool ValidateUniformMatrix(ValidationContext *context,
+bool ValidateUniformMatrix(Context *context,
                            GLenum valueType,
                            GLint location,
                            GLsizei count,
                            GLboolean transpose)
 {
     if (ConvertToBool(transpose) && context->getClientMajorVersion() < 3)
     {
         context->handleError(InvalidValue());
@@ -2134,20 +2195,17 @@ bool ValidateUniformMatrix(ValidationCon
     }
 
     const LinkedUniform *uniform = nullptr;
     gl::Program *programObject   = context->getGLState().getProgram();
     return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
            ValidateUniformMatrixValue(context, valueType, uniform->type);
 }
 
-bool ValidateStateQuery(ValidationContext *context,
-                        GLenum pname,
-                        GLenum *nativeType,
-                        unsigned int *numParams)
+bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams)
 {
     if (!context->getQueryParameterInfo(pname, nativeType, numParams))
     {
         context->handleError(InvalidEnum());
         return false;
     }
 
     const Caps &caps = context->getCaps();
@@ -2188,33 +2246,31 @@ bool ValidateStateQuery(ValidationContex
                                                       "extensions enabled");
                 return false;
             }
             break;
 
         case GL_IMPLEMENTATION_COLOR_READ_TYPE:
         case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
         {
-            if (context->getGLState().getReadFramebuffer()->checkStatus(context) !=
-                GL_FRAMEBUFFER_COMPLETE)
+            Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
+            ASSERT(readFramebuffer);
+
+            if (!ValidateFramebufferComplete(context, readFramebuffer, false))
             {
-                context->handleError(InvalidOperation());
                 return false;
             }
 
-            const Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
-            ASSERT(framebuffer);
-
-            if (framebuffer->getReadBufferState() == GL_NONE)
+            if (readFramebuffer->getReadBufferState() == GL_NONE)
             {
                 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ReadBufferNone);
                 return false;
             }
 
-            const FramebufferAttachment *attachment = framebuffer->getReadColorbuffer();
+            const FramebufferAttachment *attachment = readFramebuffer->getReadColorbuffer();
             if (!attachment)
             {
                 context->handleError(InvalidOperation());
                 return false;
             }
         }
         break;
 
@@ -2226,17 +2282,98 @@ bool ValidateStateQuery(ValidationContex
     if (*numParams == 0)
     {
         return false;
     }
 
     return true;
 }
 
-bool ValidateRobustStateQuery(ValidationContext *context,
+bool ValidateGetBooleanvRobustANGLE(Context *context,
+                                    GLenum pname,
+                                    GLsizei bufSize,
+                                    GLsizei *length,
+                                    GLboolean *params)
+{
+    GLenum nativeType;
+    unsigned int numParams = 0;
+
+    if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
+
+    return true;
+}
+
+bool ValidateGetFloatvRobustANGLE(Context *context,
+                                  GLenum pname,
+                                  GLsizei bufSize,
+                                  GLsizei *length,
+                                  GLfloat *params)
+{
+    GLenum nativeType;
+    unsigned int numParams = 0;
+
+    if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
+
+    return true;
+}
+
+bool ValidateGetIntegervRobustANGLE(Context *context,
+                                    GLenum pname,
+                                    GLsizei bufSize,
+                                    GLsizei *length,
+                                    GLint *data)
+{
+    GLenum nativeType;
+    unsigned int numParams = 0;
+
+    if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
+
+    return true;
+}
+
+bool ValidateGetInteger64vRobustANGLE(Context *context,
+                                      GLenum pname,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      GLint64 *data)
+{
+    GLenum nativeType;
+    unsigned int numParams = 0;
+
+    if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
+    {
+        return false;
+    }
+
+    if (nativeType == GL_INT_64_ANGLEX)
+    {
+        CastStateValues(context, nativeType, pname, numParams, data);
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
+    return true;
+}
+
+bool ValidateRobustStateQuery(Context *context,
                               GLenum pname,
                               GLsizei bufSize,
                               GLenum *nativeType,
                               unsigned int *numParams)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
@@ -2250,31 +2387,33 @@ bool ValidateRobustStateQuery(Validation
     if (!ValidateRobustBufferSize(context, bufSize, *numParams))
     {
         return false;
     }
 
     return true;
 }
 
-bool ValidateCopyTexImageParametersBase(ValidationContext *context,
-                                        GLenum target,
+bool ValidateCopyTexImageParametersBase(Context *context,
+                                        TextureTarget target,
                                         GLint level,
                                         GLenum internalformat,
                                         bool isSubImage,
                                         GLint xoffset,
                                         GLint yoffset,
                                         GLint zoffset,
                                         GLint x,
                                         GLint y,
                                         GLsizei width,
                                         GLsizei height,
                                         GLint border,
                                         Format *textureFormatOut)
 {
+    TextureType texType = TextureTargetToType(target);
+
     if (xoffset < 0 || yoffset < 0 || zoffset < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
         return false;
     }
 
     if (width < 0 || height < 0)
     {
@@ -2290,33 +2429,31 @@ bool ValidateCopyTexImageParametersBase(
     }
 
     if (border != 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
         return false;
     }
 
-    if (!ValidMipLevel(context, target, level))
+    if (!ValidMipLevel(context, texType, level))
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
         return false;
     }
 
-    const auto &state    = context->getGLState();
+    const gl::State &state       = context->getGLState();
     Framebuffer *readFramebuffer = state.getReadFramebuffer();
-    if (readFramebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
-    {
-        context->handleError(InvalidFramebufferOperation());
-        return false;
-    }
-
-    if (readFramebuffer->id() != 0 && readFramebuffer->getSamples(context) != 0)
-    {
-        context->handleError(InvalidOperation());
+    if (!ValidateFramebufferComplete(context, readFramebuffer, true))
+    {
+        return false;
+    }
+
+    if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
+    {
         return false;
     }
 
     if (readFramebuffer->getReadBufferState() == GL_NONE)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ReadBufferNone);
         return false;
     }
@@ -2341,50 +2478,44 @@ bool ValidateCopyTexImageParametersBase(
         context->handleError(InvalidFramebufferOperation()
                              << "The active read framebuffer object has multiview attachments.");
         return false;
     }
 
     const gl::Caps &caps = context->getCaps();
 
     GLuint maxDimension = 0;
-    switch (target)
-    {
-        case GL_TEXTURE_2D:
+    switch (texType)
+    {
+        case TextureType::_2D:
             maxDimension = caps.max2DTextureSize;
             break;
 
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+        case TextureType::CubeMap:
             maxDimension = caps.maxCubeMapTextureSize;
             break;
 
-        case GL_TEXTURE_RECTANGLE_ANGLE:
+        case TextureType::Rectangle:
             maxDimension = caps.maxRectangleTextureSize;
             break;
 
-        case GL_TEXTURE_2D_ARRAY:
+        case TextureType::_2DArray:
             maxDimension = caps.max2DTextureSize;
             break;
 
-        case GL_TEXTURE_3D:
+        case TextureType::_3D:
             maxDimension = caps.max3DTextureSize;
             break;
 
         default:
             context->handleError(InvalidEnum());
             return false;
     }
 
-    gl::Texture *texture =
-        state.getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+    gl::Texture *texture = state.getTargetTexture(texType);
     if (!texture)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
         return false;
     }
 
     if (texture->getImmutableFormat() && !isSubImage)
     {
@@ -2409,17 +2540,17 @@ bool ValidateCopyTexImageParametersBase(
             static_cast<size_t>(zoffset) >= texture->getDepth(target, level))
         {
             context->handleError(InvalidValue());
             return false;
         }
     }
     else
     {
-        if (IsCubeMapTextureTarget(target) && width != height)
+        if (texType == TextureType::CubeMap && width != height)
         {
             ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapIncomplete);
             return false;
         }
 
         if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
         {
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
@@ -2448,43 +2579,54 @@ bool ValidateCopyTexImageParametersBase(
             ANGLE_VALIDATION_ERR(context, InvalidOperation(), FeedbackLoop);
             return false;
         }
     }
 
     return true;
 }
 
-bool ValidateDrawBase(ValidationContext *context, GLenum mode, GLsizei count)
-{
+bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count)
+{
+    const Extensions &extensions = context->getExtensions();
+
     switch (mode)
     {
         case GL_POINTS:
         case GL_LINES:
         case GL_LINE_LOOP:
         case GL_LINE_STRIP:
         case GL_TRIANGLES:
         case GL_TRIANGLE_STRIP:
         case GL_TRIANGLE_FAN:
             break;
+
+        case GL_LINES_ADJACENCY_EXT:
+        case GL_LINE_STRIP_ADJACENCY_EXT:
+        case GL_TRIANGLES_ADJACENCY_EXT:
+        case GL_TRIANGLE_STRIP_ADJACENCY_EXT:
+            if (!extensions.geometryShader)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
+                return false;
+            }
+            break;
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDrawMode);
             return false;
     }
 
     if (count < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
         return false;
     }
 
     const State &state = context->getGLState();
 
-    const Extensions &extensions = context->getExtensions();
-
     // WebGL buffers cannot be mapped/unmapped because the MapBufferRange, FlushMappedBufferRange,
     // and UnmapBuffer entry points are removed from the WebGL 2.0 API.
     // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
     if (!extensions.webglCompatibility)
     {
         // Check for mapped buffers
         // TODO(jmadill): Optimize this check for non - WebGL contexts.
         if (state.hasMappedBuffer(BufferBinding::Array))
@@ -2494,59 +2636,66 @@ bool ValidateDrawBase(ValidationContext 
         }
     }
 
     // Note: these separate values are not supported in WebGL, due to D3D's limitations. See
     // Section 6.10 of the WebGL 1.0 spec.
     Framebuffer *framebuffer = state.getDrawFramebuffer();
     if (context->getLimitations().noSeparateStencilRefsAndMasks || extensions.webglCompatibility)
     {
+        ASSERT(framebuffer);
         const FramebufferAttachment *dsAttachment =
             framebuffer->getStencilOrDepthStencilAttachment();
-        GLuint stencilBits                = dsAttachment ? dsAttachment->getStencilSize() : 0;
-        GLuint minimumRequiredStencilMask = (1 << stencilBits) - 1;
+        const GLuint stencilBits = dsAttachment ? dsAttachment->getStencilSize() : 0;
+        ASSERT(stencilBits <= 8);
+
         const DepthStencilState &depthStencilState = state.getDepthStencilState();
-
-        bool differentRefs = state.getStencilRef() != state.getStencilBackRef();
-        bool differentWritemasks =
-            (depthStencilState.stencilWritemask & minimumRequiredStencilMask) !=
-            (depthStencilState.stencilBackWritemask & minimumRequiredStencilMask);
-        bool differentMasks = (depthStencilState.stencilMask & minimumRequiredStencilMask) !=
-                              (depthStencilState.stencilBackMask & minimumRequiredStencilMask);
-
-        if (differentRefs || differentWritemasks || differentMasks)
+        if (depthStencilState.stencilTest && stencilBits > 0)
         {
-            if (!extensions.webglCompatibility)
+            GLuint maxStencilValue = (1 << stencilBits) - 1;
+
+            bool differentRefs =
+                clamp(state.getStencilRef(), 0, static_cast<GLint>(maxStencilValue)) !=
+                clamp(state.getStencilBackRef(), 0, static_cast<GLint>(maxStencilValue));
+            bool differentWritemasks = (depthStencilState.stencilWritemask & maxStencilValue) !=
+                                       (depthStencilState.stencilBackWritemask & maxStencilValue);
+            bool differentMasks = (depthStencilState.stencilMask & maxStencilValue) !=
+                                  (depthStencilState.stencilBackMask & maxStencilValue);
+
+            if (differentRefs || differentWritemasks || differentMasks)
             {
-                ERR() << "This ANGLE implementation does not support separate front/back stencil "
-                         "writemasks, reference values, or stencil mask values.";
+                if (!extensions.webglCompatibility)
+                {
+                    ERR() << "This ANGLE implementation does not support separate front/back "
+                             "stencil writemasks, reference values, or stencil mask values.";
+                }
+                ANGLE_VALIDATION_ERR(context, InvalidOperation(), StencilReferenceMaskOrMismatch);
+                return false;
             }
-            ANGLE_VALIDATION_ERR(context, InvalidOperation(), StencilReferenceMaskOrMismatch);
-            return false;
         }
     }
 
-    if (framebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
-    {
-        context->handleError(InvalidFramebufferOperation());
+    if (!ValidateFramebufferComplete(context, framebuffer, true))
+    {
         return false;
     }
 
     gl::Program *program = state.getProgram();
     if (!program)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
         return false;
     }
 
     // In OpenGL ES spec for UseProgram at section 7.3, trying to render without
     // vertex shader stage or fragment shader stage is a undefined behaviour.
     // But ANGLE should clearly generate an INVALID_OPERATION error instead of
     // produce undefined result.
-    if (!program->hasLinkedVertexShader() || !program->hasLinkedFragmentShader())
+    if (!program->hasLinkedShaderStage(ShaderType::Vertex) ||
+        !program->hasLinkedShaderStage(ShaderType::Fragment))
     {
         context->handleError(InvalidOperation() << "It is a undefined behaviour to render without "
                                                    "vertex shader stage or fragment shader stage.");
         return false;
     }
 
     if (!program->validateSamplers(nullptr, context->getCaps()))
     {
@@ -2582,54 +2731,75 @@ bool ValidateDrawBase(ValidationContext 
             context->handleError(InvalidOperation() << "There is an active query for target "
                                                        "GL_TIME_ELAPSED_EXT when the number of "
                                                        "views in the active draw framebuffer is "
                                                        "greater than 1.");
             return false;
         }
     }
 
+    // Do geometry shader specific validations
+    if (program->hasLinkedShaderStage(ShaderType::Geometry))
+    {
+        if (!IsCompatibleDrawModeWithGeometryShader(mode,
+                                                    program->getGeometryShaderInputPrimitiveType()))
+        {
+            ANGLE_VALIDATION_ERR(context, InvalidOperation(),
+                                 IncompatibleDrawModeAgainstGeometryShader);
+            return false;
+        }
+    }
+
     // Uniform buffer validation
     for (unsigned int uniformBlockIndex = 0;
          uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
     {
         const gl::InterfaceBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
-        GLuint blockBinding                  = program->getUniformBlockBinding(uniformBlockIndex);
+        GLuint blockBinding                    = program->getUniformBlockBinding(uniformBlockIndex);
         const OffsetBindingPointer<Buffer> &uniformBuffer =
             state.getIndexedUniformBuffer(blockBinding);
 
         if (uniformBuffer.get() == nullptr)
         {
             // undefined behaviour
             context->handleError(
                 InvalidOperation()
                 << "It is undefined behaviour to have a used but unbound uniform buffer.");
             return false;
         }
 
-        size_t uniformBufferSize = uniformBuffer.getSize();
-        if (uniformBufferSize == 0)
-        {
-            // Bind the whole buffer.
-            uniformBufferSize = static_cast<size_t>(uniformBuffer->getSize());
-        }
-
+        size_t uniformBufferSize = GetBoundBufferAvailableSize(uniformBuffer);
         if (uniformBufferSize < uniformBlock.dataSize)
         {
             // undefined behaviour
             context->handleError(
                 InvalidOperation()
                 << "It is undefined behaviour to use a uniform buffer that is too small.");
             return false;
         }
+
+        if (extensions.webglCompatibility &&
+            uniformBuffer->isBoundForTransformFeedbackAndOtherUse())
+        {
+            ANGLE_VALIDATION_ERR(context, InvalidOperation(),
+                                 UniformBufferBoundForTransformFeedback);
+            return false;
+        }
     }
 
     // Do some additonal WebGL-specific validation
     if (extensions.webglCompatibility)
     {
+        const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
+        if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
+            transformFeedbackObject->buffersBoundForOtherUse())
+        {
+            ANGLE_VALIDATION_ERR(context, InvalidOperation(), TransformFeedbackBufferDoubleBound);
+            return false;
+        }
         // Detect rendering feedback loops for WebGL.
         if (framebuffer->formsRenderingFeedbackLoopWith(state))
         {
             ANGLE_VALIDATION_ERR(context, InvalidOperation(), FeedbackLoop);
             return false;
         }
 
         // Detect that the vertex shader input types match the attribute types
@@ -2643,39 +2813,48 @@ bool ValidateDrawBase(ValidationContext 
         {
             return false;
         }
     }
 
     return true;
 }
 
-bool ValidateDrawArraysCommon(ValidationContext *context,
+bool ValidateDrawArraysCommon(Context *context,
                               GLenum mode,
                               GLint first,
                               GLsizei count,
                               GLsizei primcount)
 {
     if (first < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStart);
         return false;
     }
 
     const State &state                          = context->getGLState();
     gl::TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
     if (curTransformFeedback && curTransformFeedback->isActive() &&
-        !curTransformFeedback->isPaused() && curTransformFeedback->getPrimitiveMode() != mode)
-    {
-        // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
-        // that does not match the current transform feedback object's draw mode (if transform
-        // feedback
-        // is active), (3.0.2, section 2.14, pg 86)
-        ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDrawModeTransformFeedback);
-        return false;
+        !curTransformFeedback->isPaused())
+    {
+        if (curTransformFeedback->getPrimitiveMode() != mode)
+        {
+            // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
+            // that does not match the current transform feedback object's draw mode (if transform
+            // feedback
+            // is active), (3.0.2, section 2.14, pg 86)
+            ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDrawModeTransformFeedback);
+            return false;
+        }
+
+        if (!curTransformFeedback->checkBufferSpaceForDraw(count, primcount))
+        {
+            ANGLE_VALIDATION_ERR(context, InvalidOperation(), TransformFeedbackBufferTooSmall);
+            return false;
+        }
     }
 
     if (!ValidateDrawBase(context, mode, count))
     {
         return false;
     }
 
     // Check the computation of maxVertex doesn't overflow.
@@ -2716,17 +2895,17 @@ bool ValidateDrawArraysInstancedANGLE(Co
     if (!ValidateDrawArraysInstancedBase(context, mode, first, count, primcount))
     {
         return false;
     }
 
     return ValidateDrawInstancedANGLE(context);
 }
 
-bool ValidateDrawElementsBase(ValidationContext *context, GLenum type)
+bool ValidateDrawElementsBase(Context *context, GLenum type)
 {
     switch (type)
     {
         case GL_UNSIGNED_BYTE:
         case GL_UNSIGNED_SHORT:
             break;
         case GL_UNSIGNED_INT:
             if (context->getClientMajorVersion() < 3 && !context->getExtensions().elementIndexUint)
@@ -2751,17 +2930,17 @@ bool ValidateDrawElementsBase(Validation
         // while transform feedback is active, (3.0.2, section 2.14, pg 86)
         context->handleError(InvalidOperation());
         return false;
     }
 
     return true;
 }
 
-bool ValidateDrawElementsCommon(ValidationContext *context,
+bool ValidateDrawElementsCommon(Context *context,
                                 GLenum mode,
                                 GLsizei count,
                                 GLenum type,
                                 const void *indices,
                                 GLsizei primcount)
 {
     if (!ValidateDrawElementsBase(context, type))
         return false;
@@ -2868,16 +3047,24 @@ bool ValidateDrawElementsCommon(Validati
         }
 
         ASSERT(isPow2(typeSize) && typeSize > 0);
         if ((elementArrayBuffer->getSize() & (typeSize - 1)) != 0)
         {
             ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedByteCountType);
             return false;
         }
+
+        if (context->getExtensions().webglCompatibility &&
+            elementArrayBuffer->isBoundForTransformFeedbackAndOtherUse())
+        {
+            ANGLE_VALIDATION_ERR(context, InvalidOperation(),
+                                 ElementArrayBufferBoundForTransformFeedback);
+            return false;
+        }
     }
 
     if (context->getExtensions().robustBufferAccessBehavior)
     {
         // Here we use maxVertex = 0 and vertexCount = 1 to avoid retrieving IndexRange when robust
         // access is enabled.
         if (!ValidateDrawAttribs(context, primcount, 0, 1))
         {
@@ -2891,47 +3078,43 @@ bool ValidateDrawElementsCommon(Validati
         if (!ValidateDrawAttribs(context, 0, 0, 0))
         {
             return false;
         }
     }
     else
     {
         // Use the parameter buffer to retrieve and cache the index range.
-        const auto &params        = context->getParams<HasIndexRange>();
-        const auto &indexRangeOpt = params.getIndexRange();
-        if (!indexRangeOpt.valid())
-        {
-            // Unexpected error.
-            return false;
-        }
+        const DrawCallParams &params = context->getParams<DrawCallParams>();
+        ANGLE_VALIDATION_TRY(params.ensureIndexRangeResolved(context));
+        const IndexRange &indexRange = params.getIndexRange();
 
         // If we use an index greater than our maximum supported index range, return an error.
         // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should always
         // return an error if possible here.
-        if (static_cast<GLuint64>(indexRangeOpt.value().end) >= context->getCaps().maxElementIndex)
+        if (static_cast<GLuint64>(indexRange.end) >= context->getCaps().maxElementIndex)
         {
             ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExceedsMaxElement);
             return false;
         }
 
-        if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(indexRangeOpt.value().end),
-                                 static_cast<GLint>(indexRangeOpt.value().vertexCount())))
+        if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(indexRange.end),
+                                 static_cast<GLint>(indexRange.vertexCount())))
         {
             return false;
         }
 
         // No op if there are no real indices in the index data (all are primitive restart).
-        return (indexRangeOpt.value().vertexIndexCount > 0);
+        return (indexRange.vertexIndexCount > 0);
     }
 
     return true;
 }
 
-bool ValidateDrawElementsInstancedCommon(ValidationContext *context,
+bool ValidateDrawElementsInstancedCommon(Context *context,
                                          GLenum mode,
                                          GLsizei count,
                                          GLenum type,
                                          const void *indices,
                                          GLsizei primcount)
 {
     return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount);
 }
@@ -3078,55 +3261,106 @@ bool ValidateGetnUniformfvEXT(Context *c
                               GLuint program,
                               GLint location,
                               GLsizei bufSize,
                               GLfloat *params)
 {
     return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
 }
 
+bool ValidateGetnUniformfvRobustANGLE(Context *context,
+                                      GLuint program,
+                                      GLint location,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      GLfloat *params)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
 bool ValidateGetnUniformivEXT(Context *context,
                               GLuint program,
                               GLint location,
                               GLsizei bufSize,
                               GLint *params)
 {
     return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
 }
 
+bool ValidateGetnUniformivRobustANGLE(Context *context,
+                                      GLuint program,
+                                      GLint location,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      GLint *params)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
+bool ValidateGetnUniformuivRobustANGLE(Context *context,
+                                       GLuint program,
+                                       GLint location,
+                                       GLsizei bufSize,
+                                       GLsizei *length,
+                                       GLuint *params)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
 bool ValidateGetUniformfvRobustANGLE(Context *context,
                                      GLuint program,
                                      GLint location,
                                      GLsizei bufSize,
                                      GLsizei *length,
                                      GLfloat *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
+    GLsizei writeLength = 0;
+
     // bufSize is validated in ValidateSizedGetUniform
-    return ValidateSizedGetUniform(context, program, location, bufSize, length);
+    if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, writeLength);
+
+    return true;
 }
 
 bool ValidateGetUniformivRobustANGLE(Context *context,
                                      GLuint program,
                                      GLint location,
                                      GLsizei bufSize,
                                      GLsizei *length,
                                      GLint *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
+    GLsizei writeLength = 0;
+
     // bufSize is validated in ValidateSizedGetUniform
-    return ValidateSizedGetUniform(context, program, location, bufSize, length);
+    if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, writeLength);
+
+    return true;
 }
 
 bool ValidateGetUniformuivRobustANGLE(Context *context,
                                       GLuint program,
                                       GLint location,
                                       GLsizei bufSize,
                                       GLsizei *length,
                                       GLuint *params)
@@ -3137,18 +3371,27 @@ bool ValidateGetUniformuivRobustANGLE(Co
     }
 
     if (context->getClientMajorVersion() < 3)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
         return false;
     }
 
+    GLsizei writeLength = 0;
+
     // bufSize is validated in ValidateSizedGetUniform
-    return ValidateSizedGetUniform(context, program, location, bufSize, length);
+    if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, writeLength);
+
+    return true;
 }
 
 bool ValidateDiscardFramebufferBase(Context *context,
                                     GLenum target,
                                     GLsizei numAttachments,
                                     const GLenum *attachments,
                                     bool defaultFramebuffer)
 {
@@ -3253,35 +3496,35 @@ bool ValidatePushGroupMarkerEXT(Context 
     if (length > 0 && marker == nullptr)
     {
         return false;
     }
 
     return true;
 }
 
-bool ValidateEGLImageTargetTexture2DOES(Context *context, GLenum target, GLeglImageOES image)
+bool ValidateEGLImageTargetTexture2DOES(Context *context, TextureType type, GLeglImageOES image)
 {
     if (!context->getExtensions().eglImage && !context->getExtensions().eglImageExternal)
     {
         context->handleError(InvalidOperation());
         return false;
     }
 
-    switch (target)
-    {
-        case GL_TEXTURE_2D:
+    switch (type)
+    {
+        case TextureType::_2D:
             if (!context->getExtensions().eglImage)
             {
                 context->handleError(InvalidEnum()
                                      << "GL_TEXTURE_2D texture target requires GL_OES_EGL_image.");
             }
             break;
 
-        case GL_TEXTURE_EXTERNAL_OES:
+        case TextureType::External:
             if (!context->getExtensions().eglImageExternal)
             {
                 context->handleError(InvalidEnum() << "GL_TEXTURE_EXTERNAL_OES texture target "
                                                       "requires GL_OES_EGL_image_external.");
             }
             break;
 
         default:
@@ -3426,17 +3669,17 @@ bool ValidateGetProgramBinaryBase(Contex
     {
         context->handleError(InvalidOperation() << "No program binary formats supported.");
         return false;
     }
 
     return true;
 }
 
-bool ValidateDrawBuffersBase(ValidationContext *context, GLsizei n, const GLenum *bufs)
+bool ValidateDrawBuffersBase(Context *context, GLsizei n, const GLenum *bufs)
 {
     // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS
     if (n < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
         return false;
     }
     if (static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
@@ -3734,17 +3977,17 @@ bool ValidateGenOrDelete(Context *contex
     if (n < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
         return false;
     }
     return true;
 }
 
-bool ValidateRobustEntryPoint(ValidationContext *context, GLsizei bufSize)
+bool ValidateRobustEntryPoint(Context *context, GLsizei bufSize)
 {
     if (!context->getExtensions().robustClientMemory)
     {
         context->handleError(InvalidOperation()
                              << "GL_ANGLE_robust_client_memory is not available.");
         return false;
     }
 
@@ -3752,17 +3995,17 @@ bool ValidateRobustEntryPoint(Validation
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
         return false;
     }
 
     return true;
 }
 
-bool ValidateRobustBufferSize(ValidationContext *context, GLsizei bufSize, GLsizei numParams)
+bool ValidateRobustBufferSize(Context *context, GLsizei bufSize, GLsizei numParams)
 {
     if (bufSize < numParams)
     {
         context->handleError(InvalidOperation() << numParams << " parameters are required but "
                                                 << bufSize << " were provided.");
         return false;
     }
 
@@ -4031,91 +4274,99 @@ bool ValidateGetFramebufferAttachmentPar
     return true;
 }
 
 bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(Context *context,
                                                             GLenum target,
                                                             GLenum attachment,
                                                             GLenum pname,
                                                             GLsizei bufSize,
-                                                            GLsizei *numParams)
+                                                            GLsizei *length,
+                                                            GLint *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
+    GLsizei numParams = 0;
     if (!ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
-                                                         numParams))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *numParams))
-    {
-        return false;
-    }
+                                                         &numParams))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
 
     return true;
 }
 
-bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context,
+bool ValidateGetBufferParameterivRobustANGLE(Context *context,
                                              BufferBinding target,
                                              GLenum pname,
                                              GLsizei bufSize,
                                              GLsizei *length,
                                              GLint *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetBufferParameterBase(context, target, pname, false, length))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
-
+    GLsizei numParams = 0;
+
+    if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
     return true;
 }
 
-bool ValidateGetBufferParameteri64vRobustANGLE(ValidationContext *context,
+bool ValidateGetBufferParameteri64vRobustANGLE(Context *context,
                                                BufferBinding target,
                                                GLenum pname,
                                                GLsizei bufSize,
                                                GLsizei *length,
                                                GLint64 *params)
 {
+    GLsizei numParams = 0;
+
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetBufferParameterBase(context, target, pname, false, length))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
+    if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
 
     return true;
 }
 
-bool ValidateGetProgramivBase(ValidationContext *context,
-                              GLuint program,
-                              GLenum pname,
-                              GLsizei *numParams)
+bool ValidateGetProgramivBase(Context *context, GLuint program, GLenum pname, GLsizei *numParams)
 {
     // Currently, all GetProgramiv queries return 1 parameter
     if (numParams)
     {
         *numParams = 1;
     }
 
     Program *programObject = GetValidProgram(context, program);
@@ -4180,233 +4431,349 @@ bool ValidateGetProgramivBase(Validation
             // An INVALID_OPERATION error is generated if COMPUTE_WORK_GROUP_SIZE is queried for a
             // program which has not been linked successfully, or which does not contain objects to
             // form a compute shader.
             if (!programObject->isLinked())
             {
                 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
                 return false;
             }
-            if (!programObject->hasLinkedComputeShader())
+            if (!programObject->hasLinkedShaderStage(ShaderType::Compute))
             {
                 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveComputeShaderStage);
                 return false;
             }
             break;
 
+        case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
+        case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
+        case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
+        case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
+            if (!context->getExtensions().geometryShader)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
+                return false;
+            }
+
+            // [EXT_geometry_shader] Chapter 7.12
+            // An INVALID_OPERATION error is generated if GEOMETRY_LINKED_VERTICES_OUT_EXT,
+            // GEOMETRY_LINKED_INPUT_TYPE_EXT, GEOMETRY_LINKED_OUTPUT_TYPE_EXT, or
+            // GEOMETRY_SHADER_INVOCATIONS_EXT are queried for a program which has not been linked
+            // successfully, or which does not contain objects to form a geometry shader.
+            if (!programObject->isLinked())
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
+                return false;
+            }
+            if (!programObject->hasLinkedShaderStage(ShaderType::Geometry))
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveGeometryShaderStage);
+                return false;
+            }
+            break;
+
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
             return false;
     }
 
     return true;
 }
 
 bool ValidateGetProgramivRobustANGLE(Context *context,
                                      GLuint program,
                                      GLenum pname,
                                      GLsizei bufSize,
-                                     GLsizei *numParams)
+                                     GLsizei *length,
+                                     GLint *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetProgramivBase(context, program, pname, numParams))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *numParams))
-    {
-        return false;
-    }
+    GLsizei numParams = 0;
+
+    if (!ValidateGetProgramivBase(context, program, pname, &numParams))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
 
     return true;
 }
 
 bool ValidateGetRenderbufferParameterivRobustANGLE(Context *context,
                                                    GLenum target,
                                                    GLenum pname,
                                                    GLsizei bufSize,
                                                    GLsizei *length,
                                                    GLint *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetRenderbufferParameterivBase(context, target, pname, length))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
+    GLsizei numParams = 0;
+
+    if (!ValidateGetRenderbufferParameterivBase(context, target, pname, &numParams))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
 
     return true;
 }
 
 bool ValidateGetShaderivRobustANGLE(Context *context,
                                     GLuint shader,
                                     GLenum pname,
                                     GLsizei bufSize,
                                     GLsizei *length,
                                     GLint *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetShaderivBase(context, shader, pname, length))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
+    GLsizei numParams = 0;
+
+    if (!ValidateGetShaderivBase(context, shader, pname, &numParams))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
 
     return true;
 }
 
 bool ValidateGetTexParameterfvRobustANGLE(Context *context,
-                                          GLenum target,
+                                          TextureType target,
                                           GLenum pname,
                                           GLsizei bufSize,
                                           GLsizei *length,
                                           GLfloat *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetTexParameterBase(context, target, pname, length))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
+    GLsizei numParams = 0;
+
+    if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
 
     return true;
 }
 
 bool ValidateGetTexParameterivRobustANGLE(Context *context,
-                                          GLenum target,
+                                          TextureType target,
                                           GLenum pname,
                                           GLsizei bufSize,
                                           GLsizei *length,
                                           GLint *params)
 {
+
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
-
-    if (!ValidateGetTexParameterBase(context, target, pname, length))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
-
+    GLsizei numParams = 0;
+    if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
     return true;
 }
 
+bool ValidateGetTexParameterIivRobustANGLE(Context *context,
+                                           TextureType target,
+                                           GLenum pname,
+                                           GLsizei bufSize,
+                                           GLsizei *length,
+                                           GLint *params)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
+bool ValidateGetTexParameterIuivRobustANGLE(Context *context,
+                                            TextureType target,
+                                            GLenum pname,
+                                            GLsizei bufSize,
+                                            GLsizei *length,
+                                            GLuint *params)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
 bool ValidateTexParameterfvRobustANGLE(Context *context,
-                                       GLenum target,
+                                       TextureType target,
                                        GLenum pname,
                                        GLsizei bufSize,
                                        const GLfloat *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
     return ValidateTexParameterBase(context, target, pname, bufSize, params);
 }
 
 bool ValidateTexParameterivRobustANGLE(Context *context,
-                                       GLenum target,
+                                       TextureType target,
                                        GLenum pname,
                                        GLsizei bufSize,
                                        const GLint *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
     return ValidateTexParameterBase(context, target, pname, bufSize, params);
 }
 
+bool ValidateTexParameterIivRobustANGLE(Context *context,
+                                        TextureType target,
+                                        GLenum pname,
+                                        GLsizei bufSize,
+                                        const GLint *params)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
+bool ValidateTexParameterIuivRobustANGLE(Context *context,
+                                         TextureType target,
+                                         GLenum pname,
+                                         GLsizei bufSize,
+                                         const GLuint *params)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
 bool ValidateGetSamplerParameterfvRobustANGLE(Context *context,
                                               GLuint sampler,
                                               GLenum pname,
                                               GLuint bufSize,
                                               GLsizei *length,
                                               GLfloat *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetSamplerParameterBase(context, sampler, pname, length))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
-
+    GLsizei numParams = 0;
+
+    if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
     return true;
 }
 
 bool ValidateGetSamplerParameterivRobustANGLE(Context *context,
                                               GLuint sampler,
                                               GLenum pname,
-                                              GLuint bufSize,
+                                              GLsizei bufSize,
                                               GLsizei *length,
                                               GLint *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetSamplerParameterBase(context, sampler, pname, length))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
-
+    GLsizei numParams = 0;
+
+    if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
     return true;
 }
 
+bool ValidateGetSamplerParameterIivRobustANGLE(Context *context,
+                                               GLuint sampler,
+                                               GLenum pname,
+                                               GLsizei bufSize,
+                                               GLsizei *length,
+                                               GLint *params)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
+bool ValidateGetSamplerParameterIuivRobustANGLE(Context *context,
+                                                GLuint sampler,
+                                                GLenum pname,
+                                                GLsizei bufSize,
+                                                GLsizei *length,
+                                                GLuint *params)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
 bool ValidateSamplerParameterfvRobustANGLE(Context *context,
                                            GLuint sampler,
                                            GLenum pname,
                                            GLsizei bufSize,
                                            const GLfloat *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
@@ -4425,137 +4792,176 @@ bool ValidateSamplerParameterivRobustANG
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
     return ValidateSamplerParameterBase(context, sampler, pname, bufSize, params);
 }
 
+bool ValidateSamplerParameterIivRobustANGLE(Context *context,
+                                            GLuint sampler,
+                                            GLenum pname,
+                                            GLsizei bufSize,
+                                            const GLint *param)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
+bool ValidateSamplerParameterIuivRobustANGLE(Context *context,
+                                             GLuint sampler,
+                                             GLenum pname,
+                                             GLsizei bufSize,
+                                             const GLuint *param)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
 bool ValidateGetVertexAttribfvRobustANGLE(Context *context,
                                           GLuint index,
                                           GLenum pname,
                                           GLsizei bufSize,
                                           GLsizei *length,
                                           GLfloat *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetVertexAttribBase(context, index, pname, length, false, false))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
-
+    GLsizei writeLength = 0;
+
+    if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, writeLength))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, writeLength);
     return true;
 }
 
 bool ValidateGetVertexAttribivRobustANGLE(Context *context,
                                           GLuint index,
                                           GLenum pname,
                                           GLsizei bufSize,
                                           GLsizei *length,
                                           GLint *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetVertexAttribBase(context, index, pname, length, false, false))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
+    GLsizei writeLength = 0;
+
+    if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, writeLength))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, writeLength);
 
     return true;
 }
 
 bool ValidateGetVertexAttribPointervRobustANGLE(Context *context,
                                                 GLuint index,
                                                 GLenum pname,
                                                 GLsizei bufSize,
                                                 GLsizei *length,
                                                 void **pointer)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetVertexAttribBase(context, index, pname, length, true, false))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
+    GLsizei writeLength = 0;
+
+    if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, true, false))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, writeLength))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, writeLength);
 
     return true;
 }
 
 bool ValidateGetVertexAttribIivRobustANGLE(Context *context,
                                            GLuint index,
                                            GLenum pname,
                                            GLsizei bufSize,
                                            GLsizei *length,
                                            GLint *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetVertexAttribBase(context, index, pname, length, false, true))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
+    GLsizei writeLength = 0;
+
+    if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, writeLength))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, writeLength);
 
     return true;
 }
 
 bool ValidateGetVertexAttribIuivRobustANGLE(Context *context,
                                             GLuint index,
                                             GLenum pname,
                                             GLsizei bufSize,
                                             GLsizei *length,
                                             GLuint *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetVertexAttribBase(context, index, pname, length, false, true))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
+    GLsizei writeLength = 0;
+
+    if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, writeLength))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, writeLength);
 
     return true;
 }
 
 bool ValidateGetActiveUniformBlockivRobustANGLE(Context *context,
                                                 GLuint program,
                                                 GLuint uniformBlockIndex,
                                                 GLenum pname,
@@ -4563,25 +4969,30 @@ bool ValidateGetActiveUniformBlockivRobu
                                                 GLsizei *length,
                                                 GLint *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname, length))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
+    GLsizei writeLength = 0;
+
+    if (!ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname,
+                                             &writeLength))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, writeLength))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, writeLength);
 
     return true;
 }
 
 bool ValidateGetInternalFormativRobustANGLE(Context *context,
                                             GLenum target,
                                             GLenum internalformat,
                                             GLenum pname,
@@ -4589,30 +5000,35 @@ bool ValidateGetInternalFormativRobustAN
                                             GLsizei *length,
                                             GLint *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize, length))
-    {
-        return false;
-    }
-
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
-    {
-        return false;
-    }
+    GLsizei numParams = 0;
+
+    if (!ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize,
+                                         &numParams))
+    {
+        return false;
+    }
+
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
+    {
+        return false;
+    }
+
+    SetRobustLengthParam(length, numParams);
 
     return true;
 }
 
-bool ValidateVertexFormatBase(ValidationContext *context,
+bool ValidateVertexFormatBase(Context *context,
                               GLuint attribIndex,
                               GLint size,
                               GLenum type,
                               GLboolean pureInteger)
 {
     const Caps &caps = context->getCaps();
     if (attribIndex >= caps.maxVertexAttributes)
     {
@@ -4696,17 +5112,17 @@ bool ValidateVertexFormatBase(Validation
 
     return true;
 }
 
 // Perform validation from WebGL 2 section 5.10 "Invalid Clears":
 // In the WebGL 2 API, trying to perform a clear when there is a mismatch between the type of the
 // specified clear value and the type of a buffer that is being cleared generates an
 // INVALID_OPERATION error instead of producing undefined results
-bool ValidateWebGLFramebufferAttachmentClearType(ValidationContext *context,
+bool ValidateWebGLFramebufferAttachmentClearType(Context *context,
                                                  GLint drawbuffer,
                                                  const GLenum *validComponentTypes,
                                                  size_t validComponentTypeCount)
 {
     const FramebufferAttachment *attachment =
         context->getGLState().getDrawFramebuffer()->getDrawBuffer(drawbuffer);
     if (attachment)
     {
@@ -4719,19 +5135,17 @@ bool ValidateWebGLFramebufferAttachmentC
                 << "No defined conversion between clear value and attachment format.");
             return false;
         }
     }
 
     return true;
 }
 
-bool ValidateRobustCompressedTexImageBase(ValidationContext *context,
-                                          GLsizei imageSize,
-                                          GLsizei dataSize)
+bool ValidateRobustCompressedTexImageBase(Context *context, GLsizei imageSize, GLsizei dataSize)
 {
     if (!ValidateRobustEntryPoint(context, dataSize))
     {
         return false;
     }
 
     gl::Buffer *pixelUnpackBuffer =
         context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
@@ -4740,17 +5154,17 @@ bool ValidateRobustCompressedTexImageBas
         if (dataSize < imageSize)
         {
             context->handleError(InvalidOperation() << "dataSize must be at least " << imageSize);
         }
     }
     return true;
 }
 
-bool ValidateGetBufferParameterBase(ValidationContext *context,
+bool ValidateGetBufferParameterBase(Context *context,
                                     BufferBinding target,
                                     GLenum pname,
                                     bool pointerVersion,
                                     GLsizei *numParams)
 {
     if (numParams)
     {
         *numParams = 0;
@@ -4926,17 +5340,20 @@ bool ValidateGetShaderivBase(Context *co
 
     if (length)
     {
         *length = 1;
     }
     return true;
 }
 
-bool ValidateGetTexParameterBase(Context *context, GLenum target, GLenum pname, GLsizei *length)
+bool ValidateGetTexParameterBase(Context *context,
+                                 TextureType target,
+                                 GLenum pname,
+                                 GLsizei *length)
 {
     if (length)
     {
         *length = 0;
     }
 
     if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
     {
@@ -5157,29 +5574,27 @@ bool ValidateReadPixelsBase(Context *con
     if (width < 0 || height < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
         return false;
     }
 
     Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
 
-    if (readFramebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
-    {
-        context->handleError(InvalidFramebufferOperation());
-        return false;
-    }
-
-    if (readFramebuffer->id() != 0 && readFramebuffer->getSamples(context) != 0)
-    {
-        context->handleError(InvalidOperation());
-        return false;
-    }
-
-    const Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
+    if (!ValidateFramebufferComplete(context, readFramebuffer, true))
+    {
+        return false;
+    }
+
+    if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
+    {
+        return false;
+    }
+
+    Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
     ASSERT(framebuffer);
 
     if (framebuffer->getReadBufferState() == GL_NONE)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ReadBufferNone);
         return false;
     }
 
@@ -5221,18 +5636,22 @@ bool ValidateReadPixelsBase(Context *con
 
         if (!ValidReadPixelsTypeEnum(context, type))
         {
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
             return false;
         }
     }
 
-    GLenum currentFormat        = framebuffer->getImplementationColorReadFormat(context);
-    GLenum currentType          = framebuffer->getImplementationColorReadType(context);
+    GLenum currentFormat = GL_NONE;
+    ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadFormat(context, &currentFormat));
+
+    GLenum currentType = GL_NONE;
+    ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadType(context, &currentType));
+
     GLenum currentComponentType = readBuffer->getFormat().info->componentType;
 
     bool validFormatTypeCombination =
         ValidReadPixelsFormatType(context, currentComponentType, format, type);
 
     if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
@@ -5242,24 +5661,30 @@ bool ValidateReadPixelsBase(Context *con
     // Check for pixel pack buffer related API errors
     gl::Buffer *pixelPackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelPack);
     if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped())
     {
         // ...the buffer object's data store is currently mapped.
         context->handleError(InvalidOperation() << "Pixel pack buffer is mapped.");
         return false;
     }
+    if (context->getExtensions().webglCompatibility && pixelPackBuffer != nullptr &&
+        pixelPackBuffer->isBoundForTransformFeedbackAndOtherUse())
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelPackBufferBoundForTransformFeedback);
+        return false;
+    }
 
     // ..  the data would be packed to the buffer object such that the memory writes required
     // would exceed the data store size.
     const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
     const gl::Extents size(width, height, 1);
     const auto &pack = context->getGLState().getPackState();
 
-    auto endByteOrErr = formatInfo.computePackUnpackEndByte(size, pack, false);
+    auto endByteOrErr = formatInfo.computePackUnpackEndByte(type, size, pack, false);
     if (endByteOrErr.isError())
     {
         context->handleError(endByteOrErr.getError());
         return false;
     }
 
     size_t endByte = endByteOrErr.getResult();
     if (bufSize >= 0)
@@ -5350,17 +5775,17 @@ bool ValidateReadPixelsBase(Context *con
         *rows = writtenRows;
     }
 
     return true;
 }
 
 template <typename ParamType>
 bool ValidateTexParameterBase(Context *context,
-                              GLenum target,
+                              TextureType target,
                               GLenum pname,
                               GLsizei bufSize,
                               const ParamType *params)
 {
     if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
         return false;
@@ -5393,31 +5818,30 @@ bool ValidateTexParameterBase(Context *c
         case GL_TEXTURE_COMPARE_FUNC:
         case GL_TEXTURE_MIN_LOD:
         case GL_TEXTURE_MAX_LOD:
             if (context->getClientMajorVersion() < 3)
             {
                 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
                 return false;
             }
-            if (target == GL_TEXTURE_EXTERNAL_OES &&
-                !context->getExtensions().eglImageExternalEssl3)
+            if (target == TextureType::External && !context->getExtensions().eglImageExternalEssl3)
             {
                 context->handleError(InvalidEnum() << "ES3 texture parameters are not "
                                                       "available without "
                                                       "GL_OES_EGL_image_external_essl3.");
                 return false;
             }
             break;
 
         default:
             break;
     }
 
-    if (target == GL_TEXTURE_2D_MULTISAMPLE)
+    if (target == TextureType::_2DMultisample)
     {
         switch (pname)
         {
             case GL_TEXTURE_MIN_FILTER:
             case GL_TEXTURE_MAG_FILTER:
             case GL_TEXTURE_WRAP_S:
             case GL_TEXTURE_WRAP_T:
             case GL_TEXTURE_WRAP_R:
@@ -5431,36 +5855,36 @@ bool ValidateTexParameterBase(Context *c
         }
     }
 
     switch (pname)
     {
         case GL_TEXTURE_WRAP_S:
         case GL_TEXTURE_WRAP_T:
         case GL_TEXTURE_WRAP_R:
+        {
+            bool restrictedWrapModes =
+                target == TextureType::External || target == TextureType::Rectangle;
+            if (!ValidateTextureWrapModeValue(context, params, restrictedWrapModes))
             {
-                bool restrictedWrapModes =
-                    target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ANGLE;
-                if (!ValidateTextureWrapModeValue(context, params, restrictedWrapModes))
-                {
-                    return false;
-                }
+                return false;
             }
-            break;
+        }
+        break;
 
         case GL_TEXTURE_MIN_FILTER:
+        {
+            bool restrictedMinFilter =
+                target == TextureType::External || target == TextureType::Rectangle;
+            if (!ValidateTextureMinFilterValue(context, params, restrictedMinFilter))
             {
-                bool restrictedMinFilter =
-                    target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ANGLE;
-                if (!ValidateTextureMinFilterValue(context, params, restrictedMinFilter))
-                {
-                    return false;
-                }
+                return false;
             }
-            break;
+        }
+        break;
 
         case GL_TEXTURE_MAG_FILTER:
             if (!ValidateTextureMagFilterValue(context, params))
             {
                 return false;
             }
             break;
 
@@ -5479,25 +5903,25 @@ bool ValidateTexParameterBase(Context *c
 
                 default:
                     ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
                     return false;
             }
             break;
 
         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+        {
+            GLfloat paramValue = static_cast<GLfloat>(params[0]);
+            if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
             {
-                GLfloat paramValue = static_cast<GLfloat>(params[0]);
-                if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
-                {
-                    return false;
-                }
-                ASSERT(static_cast<ParamType>(paramValue) == params[0]);
+                return false;
             }
-            break;
+            ASSERT(static_cast<ParamType>(paramValue) == params[0]);
+        }
+        break;
 
         case GL_TEXTURE_MIN_LOD:
         case GL_TEXTURE_MAX_LOD:
             // any value is permissible
             break;
 
         case GL_TEXTURE_COMPARE_MODE:
             if (!ValidateTextureCompareModeValue(context, params))
@@ -5534,29 +5958,29 @@ bool ValidateTexParameterBase(Context *c
             break;
 
         case GL_TEXTURE_BASE_LEVEL:
             if (ConvertToGLint(params[0]) < 0)
             {
                 context->handleError(InvalidValue() << "Base level must be at least 0.");
                 return false;
             }
-            if (target == GL_TEXTURE_EXTERNAL_OES && static_cast<GLuint>(params[0]) != 0)
+            if (target == TextureType::External && static_cast<GLuint>(params[0]) != 0)
             {
                 context->handleError(InvalidOperation()
                                      << "Base level must be 0 for external textures.");
                 return false;
             }
-            if (target == GL_TEXTURE_2D_MULTISAMPLE && static_cast<GLuint>(params[0]) != 0)
+            if (target == TextureType::_2DMultisample && static_cast<GLuint>(params[0]) != 0)
             {
                 context->handleError(InvalidOperation()
                                      << "Base level must be 0 for multisampled textures.");
                 return false;
             }
-            if (target == GL_TEXTURE_RECTANGLE_ANGLE && static_cast<GLuint>(params[0]) != 0)
+            if (target == TextureType::Rectangle && static_cast<GLuint>(params[0]) != 0)
             {
                 context->handleError(InvalidOperation()
                                      << "Base level must be 0 for rectangle textures.");
                 return false;
             }
             break;
 
         case GL_TEXTURE_MAX_LEVEL:
@@ -5595,20 +6019,20 @@ bool ValidateTexParameterBase(Context *c
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
             return false;
     }
 
     return true;
 }
 
-template bool ValidateTexParameterBase(Context *, GLenum, GLenum, GLsizei, const GLfloat *);
-template bool ValidateTexParameterBase(Context *, GLenum, GLenum, GLsizei, const GLint *);
-
-bool ValidateVertexAttribIndex(ValidationContext *context, GLuint index)
+template bool ValidateTexParameterBase(Context *, TextureType, GLenum, GLsizei, const GLfloat *);
+template bool ValidateTexParameterBase(Context *, TextureType, GLenum, GLsizei, const GLint *);
+
+bool ValidateVertexAttribIndex(Context *context, GLuint index)
 {
     if (index >= MAX_VERTEX_ATTRIBS)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
         return false;
     }
 
     return true;
@@ -5907,9 +6331,53 @@ bool ValidateGetInternalFormativBase(Con
     {
         // glGetInternalFormativ will not overflow bufSize
         *numParams = std::min(bufSize, maxWriteParams);
     }
 
     return true;
 }
 
+// We should check with Khronos if returning INVALID_FRAMEBUFFER_OPERATION is OK when querying
+// implementation format info for incomplete framebuffers. It seems like these queries are
+// incongruent with the other errors.
+bool ValidateFramebufferComplete(Context *context, Framebuffer *framebuffer, bool isFramebufferOp)
+{
+    bool complete = false;
+    ANGLE_VALIDATION_TRY(framebuffer->isComplete(context, &complete));
+    if (!complete)
+    {
+        if (isFramebufferOp)
+        {
+            context->handleError(InvalidFramebufferOperation());
+        }
+        else
+        {
+            context->handleError(InvalidOperation());
+        }
+        return false;
+    }
+    return true;
+}
+
+bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuffer)
+{
+    GLint samples = 0;
+    ANGLE_VALIDATION_TRY(framebuffer->getSamples(context, &samples));
+    if (samples != 0)
+    {
+        context->handleError(InvalidOperation());
+        return false;
+    }
+    return true;
+}
+
+bool ValidateMultitextureUnit(Context *context, GLenum texture)
+{
+    if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + context->getCaps().maxMultitextureUnits)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMultitextureUnit);
+        return false;
+    }
+    return true;
+}
+
 }  // namespace gl
--- a/gfx/angle/checkout/src/libANGLE/validationES.h
+++ b/gfx/angle/checkout/src/libANGLE/validationES.h
@@ -21,82 +21,83 @@ namespace egl
 class Display;
 class Image;
 }
 
 namespace gl
 {
 class Context;
 struct Format;
+class Framebuffer;
 struct LinkedUniform;
 class Program;
 class Shader;
-class ValidationContext;
 
+void SetRobustLengthParam(GLsizei *length, GLsizei value);
 bool IsETC2EACFormat(const GLenum format);
-bool ValidTextureTarget(const ValidationContext *context, GLenum target);
-bool ValidTexture2DTarget(const ValidationContext *context, GLenum target);
-bool ValidTexture3DTarget(const ValidationContext *context, GLenum target);
-bool ValidTextureExternalTarget(const ValidationContext *context, GLenum target);
-bool ValidTexture2DDestinationTarget(const ValidationContext *context, GLenum target);
-bool ValidTexture3DDestinationTarget(const ValidationContext *context, GLenum target);
-bool ValidTexLevelDestinationTarget(const ValidationContext *context, GLenum target);
-bool ValidFramebufferTarget(const ValidationContext *context, GLenum target);
-bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level);
-bool ValidImageSizeParameters(ValidationContext *context,
-                              GLenum target,
+bool ValidTextureTarget(const Context *context, TextureType type);
+bool ValidTexture2DTarget(const Context *context, TextureType type);
+bool ValidTexture3DTarget(const Context *context, TextureType target);
+bool ValidTextureExternalTarget(const Context *context, TextureType target);
+bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget target);
+bool ValidTexture3DDestinationTarget(const Context *context, TextureType target);
+bool ValidTexLevelDestinationTarget(const Context *context, TextureType type);
+bool ValidFramebufferTarget(const Context *context, GLenum target);
+bool ValidMipLevel(const Context *context, TextureType type, GLint level);
+bool ValidImageSizeParameters(Context *context,
+                              TextureType target,
                               GLint level,
                               GLsizei width,
                               GLsizei height,
                               GLsizei depth,
                               bool isSubImage);
-bool ValidCompressedImageSize(const ValidationContext *context,
+bool ValidCompressedImageSize(const Context *context,
                               GLenum internalFormat,
                               GLint level,
                               GLsizei width,
                               GLsizei height);
-bool ValidCompressedSubImageSize(const ValidationContext *context,
+bool ValidCompressedSubImageSize(const Context *context,
                                  GLenum internalFormat,
                                  GLint xoffset,
                                  GLint yoffset,
                                  GLsizei width,
                                  GLsizei height,
                                  size_t textureWidth,
                                  size_t textureHeight);
-bool ValidImageDataSize(ValidationContext *context,
-                        GLenum textureTarget,
+bool ValidImageDataSize(Context *context,
+                        TextureType texType,
                         GLsizei width,
                         GLsizei height,
                         GLsizei depth,
                         GLenum format,
                         GLenum type,
                         const void *pixels,
                         GLsizei imageSize);
 
 bool ValidQueryType(const Context *context, GLenum queryType);
 
-bool ValidateWebGLVertexAttribPointer(ValidationContext *context,
+bool ValidateWebGLVertexAttribPointer(Context *context,
                                       GLenum type,
                                       GLboolean normalized,
                                       GLsizei stride,
                                       const void *ptr,
                                       bool pureInteger);
 
 // Returns valid program if id is a valid program name
 // Errors INVALID_OPERATION if valid shader is given and returns NULL
 // Errors INVALID_VALUE otherwise and returns NULL
-Program *GetValidProgram(ValidationContext *context, GLuint id);
+Program *GetValidProgram(Context *context, GLuint id);
 
 // Returns valid shader if id is a valid shader name
 // Errors INVALID_OPERATION if valid program is given and returns NULL
 // Errors INVALID_VALUE otherwise and returns NULL
-Shader *GetValidShader(ValidationContext *context, GLuint id);
+Shader *GetValidShader(Context *context, GLuint id);
 
 bool ValidateAttachmentTarget(Context *context, GLenum attachment);
-bool ValidateRenderbufferStorageParametersBase(ValidationContext *context,
+bool ValidateRenderbufferStorageParametersBase(Context *context,
                                                GLenum target,
                                                GLsizei samples,
                                                GLenum internalformat,
                                                GLsizei width,
                                                GLsizei height);
 bool ValidateFramebufferRenderbufferParameters(Context *context,
                                                GLenum target,
                                                GLenum attachment,
@@ -205,86 +206,104 @@ bool ValidateGetQueryObjecti64vRobustANG
 bool ValidateGetQueryObjectui64vEXT(Context *context, GLuint id, GLenum pname, GLuint64 *params);
 bool ValidateGetQueryObjectui64vRobustANGLE(Context *context,
                                             GLuint id,
                                             GLenum pname,
                                             GLsizei bufSize,
                                             GLsizei *length,
                                             GLuint64 *params);
 
-bool ValidateUniformCommonBase(ValidationContext *context,
+bool ValidateUniformCommonBase(Context *context,
                                gl::Program *program,
                                GLint location,
                                GLsizei count,
                                const LinkedUniform **uniformOut);
-bool ValidateUniform1ivValue(ValidationContext *context,
+bool ValidateUniform1ivValue(Context *context,
                              GLenum uniformType,
                              GLsizei count,
                              const GLint *value);
-bool ValidateUniformValue(ValidationContext *context, GLenum valueType, GLenum uniformType);
-bool ValidateUniformMatrixValue(ValidationContext *context, GLenum valueType, GLenum uniformType);
-bool ValidateUniform(ValidationContext *context, GLenum uniformType, GLint location, GLsizei count);
-bool ValidateUniformMatrix(ValidationContext *context,
+bool ValidateUniformValue(Context *context, GLenum valueType, GLenum uniformType);
+bool ValidateUniformMatrixValue(Context *context, GLenum valueType, GLenum uniformType);
+bool ValidateUniform(Context *context, GLenum uniformType, GLint location, GLsizei count);
+bool ValidateUniformMatrix(Context *context,
                            GLenum matrixType,
                            GLint location,
                            GLsizei count,
                            GLboolean transpose);
-
-bool ValidateStateQuery(ValidationContext *context,
+bool ValidateGetBooleanvRobustANGLE(Context *context,
+                                    GLenum pname,
+                                    GLsizei bufSize,
+                                    GLsizei *length,
+                                    GLboolean *params);
+bool ValidateGetFloatvRobustANGLE(Context *context,
+                                  GLenum pname,
+                                  GLsizei bufSize,
+                                  GLsizei *length,
+                                  GLfloat *params);
+bool ValidateStateQuery(Context *context,
                         GLenum pname,
                         GLenum *nativeType,
                         unsigned int *numParams);
-
-bool ValidateRobustStateQuery(ValidationContext *context,
+bool ValidateGetIntegervRobustANGLE(Context *context,
+                                    GLenum pname,
+                                    GLsizei bufSize,
+                                    GLsizei *length,
+                                    GLint *data);
+bool ValidateGetInteger64vRobustANGLE(Context *context,
+                                      GLenum pname,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      GLint64 *data);
+bool ValidateRobustStateQuery(Context *context,
                               GLenum pname,
                               GLsizei bufSize,
                               GLenum *nativeType,
                               unsigned int *numParams);
 
-bool ValidateCopyTexImageParametersBase(ValidationContext *context,
-                                        GLenum target,
+bool ValidateCopyTexImageParametersBase(Context *context,
+                                        TextureTarget target,
                                         GLint level,
                                         GLenum internalformat,
                                         bool isSubImage,
                                         GLint xoffset,
                                         GLint yoffset,
                                         GLint zoffset,
                                         GLint x,
                                         GLint y,
                                         GLsizei width,
                                         GLsizei height,
                                         GLint border,
                                         Format *textureFormatOut);
 
-bool ValidateDrawBase(ValidationContext *context, GLenum mode, GLsizei count);
-bool ValidateDrawArraysCommon(ValidationContext *context,
+bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count);
+bool ValidateDrawArraysCommon(Context *context,
                               GLenum mode,
                               GLint first,
                               GLsizei count,
                               GLsizei primcount);
 bool ValidateDrawArraysInstancedBase(Context *context,
                                      GLenum mode,
                                      GLint first,
                                      GLsizei count,
                                      GLsizei primcount);
 bool ValidateDrawArraysInstancedANGLE(Context *context,
                                       GLenum mode,
                                       GLint first,
                                       GLsizei count,
                                       GLsizei primcount);
 
-bool ValidateDrawElementsBase(ValidationContext *context, GLenum type);
-bool ValidateDrawElementsCommon(ValidationContext *context,
+bool ValidateDrawElementsBase(Context *context, GLenum type);
+bool ValidateDrawElementsCommon(Context *context,
                                 GLenum mode,
                                 GLsizei count,
                                 GLenum type,
                                 const void *indices,
                                 GLsizei primcount);
 
-bool ValidateDrawElementsInstancedCommon(ValidationContext *context,
+bool ValidateDrawElementsInstancedCommon(Context *context,
                                          GLenum mode,
                                          GLsizei count,
                                          GLenum type,
                                          const void *indices,
                                          GLsizei primcount);
 bool ValidateDrawElementsInstancedANGLE(Context *context,
                                         GLenum mode,
                                         GLsizei count,
@@ -299,21 +318,39 @@ bool ValidateFramebufferTextureBase(Cont
                                     GLint level);
 
 bool ValidateGetUniformBase(Context *context, GLuint program, GLint location);
 bool ValidateGetnUniformfvEXT(Context *context,
                               GLuint program,
                               GLint location,
                               GLsizei bufSize,
                               GLfloat *params);
+bool ValidateGetnUniformfvRobustANGLE(Context *context,
+                                      GLuint program,
+                                      GLint location,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      GLfloat *params);
 bool ValidateGetnUniformivEXT(Context *context,
                               GLuint program,
                               GLint location,
                               GLsizei bufSize,
                               GLint *params);
+bool ValidateGetnUniformivRobustANGLE(Context *context,
+                                      GLuint program,
+                                      GLint location,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      GLint *params);
+bool ValidateGetnUniformuivRobustANGLE(Context *context,
+                                       GLuint program,
+                                       GLint location,
+                                       GLsizei bufSize,
+                                       GLsizei *length,
+                                       GLuint *params);
 bool ValidateGetUniformfvRobustANGLE(Context *context,
                                      GLuint program,
                                      GLint location,
                                      GLsizei bufSize,
                                      GLsizei *length,
                                      GLfloat *params);
 bool ValidateGetUniformivRobustANGLE(Context *context,
                                      GLuint program,
@@ -332,17 +369,19 @@ bool ValidateDiscardFramebufferBase(Cont
                                     GLenum target,
                                     GLsizei numAttachments,
                                     const GLenum *attachments,
                                     bool defaultFramebuffer);
 
 bool ValidateInsertEventMarkerEXT(Context *context, GLsizei length, const char *marker);
 bool ValidatePushGroupMarkerEXT(Context *context, GLsizei length, const char *marker);
 
-bool ValidateEGLImageTargetTexture2DOES(Context *context, GLenum target, GLeglImageOES image);
+bool ValidateEGLImageTargetTexture2DOES(Context *context,
+                                        gl::TextureType type,
+                                        GLeglImageOES image);
 bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context,
                                                   GLenum target,
                                                   GLeglImageOES image);
 
 bool ValidateBindVertexArrayBase(Context *context, GLuint array);
 
 bool ValidateProgramBinaryBase(Context *context,
                                GLuint program,
@@ -351,17 +390,17 @@ bool ValidateProgramBinaryBase(Context *
                                GLint length);
 bool ValidateGetProgramBinaryBase(Context *context,
                                   GLuint program,
                                   GLsizei bufSize,
                                   GLsizei *length,
                                   GLenum *binaryFormat,
                                   void *binary);
 
-bool ValidateDrawBuffersBase(ValidationContext *context, GLsizei n, const GLenum *bufs);
+bool ValidateDrawBuffersBase(Context *context, GLsizei n, const GLenum *bufs);
 
 bool ValidateGetBufferPointervBase(Context *context,
                                    BufferBinding target,
                                    GLenum pname,
                                    GLsizei *length,
                                    void **params);
 bool ValidateUnmapBufferBase(Context *context, BufferBinding target);
 bool ValidateMapBufferRangeBase(Context *context,
@@ -371,59 +410,58 @@ bool ValidateMapBufferRangeBase(Context 
                                 GLbitfield access);
 bool ValidateFlushMappedBufferRangeBase(Context *context,
                                         BufferBinding target,
                                         GLintptr offset,
                                         GLsizeiptr length);
 
 bool ValidateGenOrDelete(Context *context, GLint n);
 
-bool ValidateRobustEntryPoint(ValidationContext *context, GLsizei bufSize);
-bool ValidateRobustBufferSize(ValidationContext *context, GLsizei bufSize, GLsizei numParams);
+bool ValidateRobustEntryPoint(Context *context, GLsizei bufSize);
+bool ValidateRobustBufferSize(Context *context, GLsizei bufSize, GLsizei numParams);
 
 bool ValidateGetFramebufferAttachmentParameterivBase(Context *context,
                                                      GLenum target,
                                                      GLenum attachment,
                                                      GLenum pname,
                                                      GLsizei *numParams);
 bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(Context *context,
                                                             GLenum target,
                                                             GLenum attachment,
                                                             GLenum pname,
                                                             GLsizei bufSize,
-                                                            GLsizei *numParams);
+                                                            GLsizei *length,
+                                                            GLint *params);
 
-bool ValidateGetBufferParameterBase(ValidationContext *context,
+bool ValidateGetBufferParameterBase(Context *context,
                                     BufferBinding target,
                                     GLenum pname,
                                     bool pointerVersion,
                                     GLsizei *numParams);
-bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context,
+bool ValidateGetBufferParameterivRobustANGLE(Context *context,
                                              BufferBinding target,
                                              GLenum pname,
                                              GLsizei bufSize,
                                              GLsizei *length,
                                              GLint *params);
 
-bool ValidateGetBufferParameteri64vRobustANGLE(ValidationContext *context,
+bool ValidateGetBufferParameteri64vRobustANGLE(Context *context,
                                                BufferBinding target,
                                                GLenum pname,
                                                GLsizei bufSize,
                                                GLsizei *length,
                                                GLint64 *params);
 
-bool ValidateGetProgramivBase(ValidationContext *context,
-                              GLuint program,
-                              GLenum pname,
-                              GLsizei *numParams);
+bool ValidateGetProgramivBase(Context *context, GLuint program, GLenum pname, GLsizei *numParams);
 bool ValidateGetProgramivRobustANGLE(Context *context,
                                      GLuint program,
                                      GLenum pname,
                                      GLsizei bufSize,
-                                     GLsizei *numParams);
+                                     GLsizei *length,
+                                     GLint *params);
 
 bool ValidateGetRenderbufferParameterivBase(Context *context,
                                             GLenum target,
                                             GLenum pname,
                                             GLsizei *length);
 bool ValidateGetRenderbufferParameterivRobustANGLE(Context *context,
                                                    GLenum target,
                                                    GLenum pname,
@@ -434,70 +472,117 @@ bool ValidateGetRenderbufferParameterivR
 bool ValidateGetShaderivBase(Context *context, GLuint shader, GLenum pname, GLsizei *length);
 bool ValidateGetShaderivRobustANGLE(Context *context,
                                     GLuint shader,
                                     GLenum pname,
                                     GLsizei bufSize,
                                     GLsizei *length,
                                     GLint *params);
 
-bool ValidateGetTexParameterBase(Context *context, GLenum target, GLenum pname, GLsizei *length);
+bool ValidateGetTexParameterBase(Context *context,
+                                 TextureType target,
+                                 GLenum pname,
+                                 GLsizei *length);
 bool ValidateGetTexParameterfvRobustANGLE(Context *context,
-                                          GLenum target,
+                                          TextureType target,
                                           GLenum pname,
                                           GLsizei bufSize,
                                           GLsizei *length,
                                           GLfloat *params);
 bool ValidateGetTexParameterivRobustANGLE(Context *context,
-                                          GLenum target,
+                                          TextureType target,
                                           GLenum pname,
                                           GLsizei bufSize,
                                           GLsizei *length,
                                           GLint *params);
+bool ValidateGetTexParameterIivRobustANGLE(Context *context,
+                                           TextureType target,
+                                           GLenum pname,
+                                           GLsizei bufSize,
+                                           GLsizei *length,
+                                           GLint *params);
+bool ValidateGetTexParameterIuivRobustANGLE(Context *context,
+                                            TextureType target,
+                                            GLenum pname,
+                                            GLsizei bufSize,
+                                            GLsizei *length,
+                                            GLuint *params);
 
 template <typename ParamType>
 bool ValidateTexParameterBase(Context *context,
-                              GLenum target,
+                              TextureType target,
                               GLenum pname,
                               GLsizei bufSize,
                               const ParamType *params);
 bool ValidateTexParameterfvRobustANGLE(Context *context,
-                                       GLenum target,
+                                       TextureType target,
                                        GLenum pname,
                                        GLsizei bufSize,
                                        const GLfloat *params);
 bool ValidateTexParameterivRobustANGLE(Context *context,
-                                       GLenum target,
+                                       TextureType target,
                                        GLenum pname,
                                        GLsizei bufSize,
                                        const GLint *params);
+bool ValidateTexParameterIivRobustANGLE(Context *context,
+                                        TextureType target,
+                                        GLenum pname,
+                                        GLsizei bufSize,
+                                        const GLint *params);
+bool ValidateTexParameterIuivRobustANGLE(Context *context,
+                                         TextureType target,
+                                         GLenum pname,
+                                         GLsizei bufSize,
+                                         const GLuint *params);
 
 bool ValidateGetSamplerParameterfvRobustANGLE(Context *context,
                                               GLuint sampler,
                                               GLenum pname,
                                               GLuint bufSize,
                                               GLsizei *length,
                                               GLfloat *params);
 bool ValidateGetSamplerParameterivRobustANGLE(Context *context,
                                               GLuint sampler,
                                               GLenum pname,
-                                              GLuint bufSize,
+                                              GLsizei bufSize,
                                               GLsizei *length,
                                               GLint *params);
+bool ValidateGetSamplerParameterIivRobustANGLE(Context *context,
+                                               GLuint sampler,
+                                               GLenum pname,
+                                               GLsizei bufSize,
+                                               GLsizei *length,
+                                               GLint *params);
+bool ValidateGetSamplerParameterIuivRobustANGLE(Context *context,
+                                                GLuint sampler,
+                                                GLenum pname,
+                                                GLsizei bufSize,
+                                                GLsizei *length,
+                                                GLuint *params);
 
 bool ValidateSamplerParameterfvRobustANGLE(Context *context,
                                            GLuint sampler,
                                            GLenum pname,
                                            GLsizei bufSize,
                                            const GLfloat *params);
 bool ValidateSamplerParameterivRobustANGLE(Context *context,
                                            GLuint sampler,
                                            GLenum pname,
                                            GLsizei bufSize,
                                            const GLint *params);
+bool ValidateSamplerParameterIivRobustANGLE(Context *context,
+                                            GLuint sampler,
+                                            GLenum pname,
+                                            GLsizei bufSize,
+                                            const GLint *param);
+bool ValidateSamplerParameterIuivRobustANGLE(Context *context,
+                                             GLuint sampler,
+                                             GLenum pname,
+                                             GLsizei bufSize,
+                                             const GLuint *param);
 
 bool ValidateGetVertexAttribBase(Context *context,
                                  GLuint index,
                                  GLenum pname,
                                  GLsizei *length,
                                  bool pointer,
                                  bool pureIntegerEntryPoint);
 bool ValidateGetVertexAttribfvRobustANGLE(Context *context,
@@ -546,32 +631,30 @@ bool ValidateGetActiveUniformBlockivRobu
 bool ValidateGetInternalFormativRobustANGLE(Context *context,
                                             GLenum target,
                                             GLenum internalformat,
                                             GLenum pname,
                                             GLsizei bufSize,
                                             GLsizei *length,
                                             GLint *params);
 
-bool ValidateVertexFormatBase(ValidationContext *context,
+bool ValidateVertexFormatBase(Context *context,
                               GLuint attribIndex,
                               GLint size,
                               GLenum type,
                               GLboolean pureInteger);
 
-bool ValidateWebGLFramebufferAttachmentClearType(ValidationContext *context,
+bool ValidateWebGLFramebufferAttachmentClearType(Context *context,
                                                  GLint drawbuffer,
                                                  const GLenum *validComponentTypes,
                                                  size_t validComponentTypeCount);
 
-bool ValidateRobustCompressedTexImageBase(ValidationContext *context,
-                                          GLsizei imageSize,
-                                          GLsizei dataSize);
+bool ValidateRobustCompressedTexImageBase(Context *context, GLsizei imageSize, GLsizei dataSize);
 
-bool ValidateVertexAttribIndex(ValidationContext *context, GLuint index);
+bool ValidateVertexAttribIndex(Context *context, GLuint index);
 
 bool ValidateGetActiveUniformBlockivBase(Context *context,
                                          GLuint program,
                                          GLuint uniformBlockIndex,
                                          GLenum pname,
                                          GLsizei *length);
 
 bool ValidateGetSamplerParameterBase(Context *context,
@@ -588,11 +671,22 @@ bool ValidateSamplerParameterBase(Contex
 
 bool ValidateGetInternalFormativBase(Context *context,
                                      GLenum target,
                                      GLenum internalformat,
                                      GLenum pname,
                                      GLsizei bufSize,
                                      GLsizei *numParams);
 
+bool ValidateFramebufferComplete(Context *context, Framebuffer *framebuffer, bool isFramebufferOp);
+bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuffer);
+
+bool ValidateMultitextureUnit(Context *context, GLenum texture);
+
+// Utility macro for handling implementation methods inside Validation.
+#define ANGLE_HANDLE_VALIDATION_ERR(X) \
+    context->handleError(X);           \
+    return false;
+#define ANGLE_VALIDATION_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_VALIDATION_ERR);
+
 }  // namespace gl
 
 #endif  // LIBANGLE_VALIDATION_ES_H_
--- a/gfx/angle/checkout/src/libANGLE/validationES1.cpp
+++ b/gfx/angle/checkout/src/libANGLE/validationES1.cpp
@@ -4,77 +4,111 @@
 // found in the LICENSE file.
 //
 
 // validationES1.cpp: Validation functions for OpenGL ES 1.0 entry point parameters
 
 #include "libANGLE/validationES1.h"
 
 #include "common/debug.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/validationES.h"
+
+#define ANGLE_VALIDATE_IS_GLES1(context)                              \
+    if (context->getClientMajorVersion() > 1)                         \
+    {                                                                 \
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), GLES1Only); \
+        return false;                                                 \
+    }
+
+namespace
+{
+
+bool ValidateAlphaFuncCommon(gl::Context *context, gl::AlphaTestFunc func)
+{
+    switch (func)
+    {
+        case gl::AlphaTestFunc::AlwaysPass:
+        case gl::AlphaTestFunc::Equal:
+        case gl::AlphaTestFunc::Gequal:
+        case gl::AlphaTestFunc::Greater:
+        case gl::AlphaTestFunc::Lequal:
+        case gl::AlphaTestFunc::Less:
+        case gl::AlphaTestFunc::Never:
+        case gl::AlphaTestFunc::NotEqual:
+            return true;
+        default:
+            context->handleError(gl::InvalidEnum() << gl::kErrorEnumNotSupported);
+            return false;
+    }
+}
+
+}  // anonymous namespace
 
 namespace gl
 {
 
-bool ValidateAlphaFunc(Context *context, GLenum func, GLfloat ref)
+bool ValidateAlphaFunc(Context *context, AlphaTestFunc func, GLfloat ref)
 {
-    UNIMPLEMENTED();
-    return true;
+    ANGLE_VALIDATE_IS_GLES1(context);
+    return ValidateAlphaFuncCommon(context, func);
 }
 
-bool ValidateAlphaFuncx(Context *context, GLenum func, GLfixed ref)
+bool ValidateAlphaFuncx(Context *context, AlphaTestFunc func, GLfixed ref)
 {
-    UNIMPLEMENTED();
-    return true;
+    ANGLE_VALIDATE_IS_GLES1(context);
+    return ValidateAlphaFuncCommon(context, func);
 }
 
 bool ValidateClearColorx(Context *context, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
 {
     UNIMPLEMENTED();
     return true;
 }
 
 bool ValidateClearDepthx(Context *context, GLfixed depth)
 {
     UNIMPLEMENTED();
     return true;
 }
 
 bool ValidateClientActiveTexture(Context *context, GLenum texture)
 {
-    UNIMPLEMENTED();
-    return true;
+    ANGLE_VALIDATE_IS_GLES1(context);
+    return ValidateMultitextureUnit(context, texture);
 }
 
 bool ValidateClipPlanef(Context *context, GLenum p, const GLfloat *eqn)
 {
     UNIMPLEMENTED();
     return true;
 }
 
 bool ValidateClipPlanex(Context *context, GLenum plane, const GLfixed *equation)
 {
     UNIMPLEMENTED();
     return true;
 }
 
 bool ValidateColor4f(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
 {
-    UNIMPLEMENTED();
+    ANGLE_VALIDATE_IS_GLES1(context);
     return true;
 }
 
 bool ValidateColor4ub(Context *context, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
 {
-    UNIMPLEMENTED();
+    ANGLE_VALIDATE_IS_GLES1(context);
     return true;
 }
 
 bool ValidateColor4x(Context *context, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
 {
-    UNIMPLEMENTED();
+    ANGLE_VALIDATE_IS_GLES1(context);
     return true;
 }
 
 bool ValidateColorPointer(Context *context,
                           GLint size,
                           GLenum type,
                           GLsizei stride,
                           const void *pointer)
@@ -222,17 +256,17 @@ bool ValidateGetTexEnviv(Context *contex
 }
 
 bool ValidateGetTexEnvxv(Context *context, GLenum target, GLenum pname, GLfixed *params)
 {
     UNIMPLEMENTED();
     return true;
 }
 
-bool ValidateGetTexParameterxv(Context *context, GLenum target, GLenum pname, GLfixed *params)
+bool ValidateGetTexParameterxv(Context *context, TextureType target, GLenum pname, GLfixed *params)
 {
     UNIMPLEMENTED();
     return true;
 }
 
 bool ValidateLightModelf(Context *context, GLenum pname, GLfloat param)
 {
     UNIMPLEMENTED();
@@ -284,29 +318,29 @@ bool ValidateLightxv(Context *context, G
 bool ValidateLineWidthx(Context *context, GLfixed width)
 {
     UNIMPLEMENTED();
     return true;
 }
 
 bool ValidateLoadIdentity(Context *context)
 {
-    UNIMPLEMENTED();
+    ANGLE_VALIDATE_IS_GLES1(context);
     return true;
 }
 
 bool ValidateLoadMatrixf(Context *context, const GLfloat *m)
 {
-    UNIMPLEMENTED();
+    ANGLE_VALIDATE_IS_GLES1(context);
     return true;
 }
 
 bool ValidateLoadMatrixx(Context *context, const GLfixed *m)
 {
-    UNIMPLEMENTED();
+    ANGLE_VALIDATE_IS_GLES1(context);
     return true;
 }
 
 bool ValidateLogicOp(Context *context, GLenum opcode)
 {
     UNIMPLEMENTED();
     return true;
 }
@@ -330,65 +364,74 @@ bool ValidateMaterialx(Context *context,
 }
 
 bool ValidateMaterialxv(Context *context, GLenum face, GLenum pname, const GLfixed *param)
 {
     UNIMPLEMENTED();
     return true;
 }
 
-bool ValidateMatrixMode(Context *context, GLenum mode)
+bool ValidateMatrixMode(Context *context, MatrixType mode)
 {
-    UNIMPLEMENTED();
-    return true;
+    ANGLE_VALIDATE_IS_GLES1(context);
+    switch (mode)
+    {
+        case MatrixType::Projection:
+        case MatrixType::Modelview:
+        case MatrixType::Texture:
+            return true;
+        default:
+            ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
+            return false;
+    }
 }
 
 bool ValidateMultMatrixf(Context *context, const GLfloat *m)
 {
-    UNIMPLEMENTED();
+    ANGLE_VALIDATE_IS_GLES1(context);
     return true;
 }
 
 bool ValidateMultMatrixx(Context *context, const GLfixed *m)
 {
-    UNIMPLEMENTED();
+    ANGLE_VALIDATE_IS_GLES1(context);
     return true;
 }
 
 bool ValidateMultiTexCoord4f(Context *context,
                              GLenum target,
                              GLfloat s,
                              GLfloat t,
                              GLfloat r,
                              GLfloat q)
 {
-    UNIMPLEMENTED();
-    return true;
+    ANGLE_VALIDATE_IS_GLES1(context);
+    return ValidateMultitextureUnit(context, target);
 }
 
 bool ValidateMultiTexCoord4x(Context *context,
-                             GLenum texture,
+                             GLenum target,
                              GLfixed s,
                              GLfixed t,
                              GLfixed r,
                              GLfixed q)
 {
-    UNIMPLEMENTED();
-    return true;
+    ANGLE_VALIDATE_IS_GLES1(context);
+    return ValidateMultitextureUnit(context, target);
 }
 
 bool ValidateNormal3f(Context *context, GLfloat nx, GLfloat ny, GLfloat nz)
 {
-    UNIMPLEMENTED();
+    ANGLE_VALIDATE_IS_GLES1(context);
     return true;
 }
 
 bool ValidateNormal3x(Context *context, GLfixed nx, GLfixed ny, GLfixed nz)
 {
-    UNIMPLEMENTED();
+    ANGLE_VALIDATE_IS_GLES1(context);
     return true;
 }
 
 bool ValidateNormalPointer(Context *context, GLenum type, GLsizei stride, const void *pointer)
 {
     UNIMPLEMENTED();
     return true;
 }
@@ -456,23 +499,35 @@ bool ValidatePointSizex(Context *context
 bool ValidatePolygonOffsetx(Context *context, GLfixed factor, GLfixed units)
 {
     UNIMPLEMENTED();
     return true;
 }
 
 bool ValidatePopMatrix(Context *context)
 {
-    UNIMPLEMENTED();
+    ANGLE_VALIDATE_IS_GLES1(context);
+    const auto &stack = context->getGLState().gles1().currentMatrixStack();
+    if (stack.size() == 1)
+    {
+        ANGLE_VALIDATION_ERR(context, StackUnderflow(), MatrixStackUnderflow);
+        return false;
+    }
     return true;
 }
 
 bool ValidatePushMatrix(Context *context)
 {
-    UNIMPLEMENTED();
+    ANGLE_VALIDATE_IS_GLES1(context);
+    const auto &stack = context->getGLState().gles1().currentMatrixStack();
+    if (stack.size() == stack.max_size())
+    {
+        ANGLE_VALIDATION_ERR(context, StackOverflow(), MatrixStackOverflow);
+        return false;
+    }
     return true;
 }
 
 bool ValidateRotatef(Context *context, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
 {
     UNIMPLEMENTED();
     return true;
 }
@@ -548,23 +603,26 @@ bool ValidateTexEnvx(Context *context, G
 }
 
 bool ValidateTexEnvxv(Context *context, GLenum target, GLenum pname, const GLfixed *params)
 {
     UNIMPLEMENTED();
     return true;
 }
 
-bool ValidateTexParameterx(Context *context, GLenum target, GLenum pname, GLfixed param)
+bool ValidateTexParameterx(Context *context, TextureType target, GLenum pname, GLfixed param)
 {
     UNIMPLEMENTED();
     return true;
 }
 
-bool ValidateTexParameterxv(Context *context, GLenum target, GLenum pname, const GLfixed *params)
+bool ValidateTexParameterxv(Context *context,
+                            TextureType target,
+                            GLenum pname,
+                            const GLfixed *params)
 {
     UNIMPLEMENTED();
     return true;
 }
 
 bool ValidateTranslatef(Context *context, GLfloat x, GLfloat y, GLfloat z)
 {
     UNIMPLEMENTED();
@@ -688,9 +746,175 @@ bool ValidatePointSizePointerOES(Context
     return true;
 }
 
 bool ValidateQueryMatrixxOES(Context *context, GLfixed *mantissa, GLint *exponent)
 {
     UNIMPLEMENTED();
     return true;
 }
+
+bool ValidateGenFramebuffersOES(Context *context, GLsizei n, GLuint *framebuffers)
+{
+    UNIMPLEMENTED();
+    return true;
 }
+
+bool ValidateDeleteFramebuffersOES(Context *context, GLsizei n, const GLuint *framebuffers)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateGenRenderbuffersOES(Context *context, GLsizei n, GLuint *renderbuffers)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateDeleteRenderbuffersOES(Context *context, GLsizei n, const GLuint *renderbuffers)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateBindFramebufferOES(Context *context, GLenum target, GLuint framebuffer)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateBindRenderbufferOES(Context *context, GLenum target, GLuint renderbuffer)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateCheckFramebufferStatusOES(Context *context, GLenum target)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateFramebufferRenderbufferOES(Context *context,
+                                        GLenum target,
+                                        GLenum attachment,
+                                        GLenum rbtarget,
+                                        GLuint renderbuffer)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateFramebufferTexture2DOES(Context *context,
+                                     GLenum target,
+                                     GLenum attachment,
+                                     TextureTarget textarget,
+                                     GLuint texture,
+                                     GLint level)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateGenerateMipmapOES(Context *context, TextureType target)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateGetFramebufferAttachmentParameterivOES(Context *context,
+                                                    GLenum target,
+                                                    GLenum attachment,
+                                                    GLenum pname,
+                                                    GLint *params)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateGetRenderbufferParameterivOES(Context *context,
+                                           GLenum target,
+                                           GLenum pname,
+                                           GLint *params)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateIsFramebufferOES(Context *context, GLuint framebuffer)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateIsRenderbufferOES(Context *context, GLuint renderbuffer)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateRenderbufferStorageOES(Context *context,
+                                    GLenum target,
+                                    GLint internalformat,
+                                    GLsizei width,
+                                    GLsizei height)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+// GL_OES_texture_cube_map
+
+bool ValidateGetTexGenfvOES(Context *context, GLenum coord, GLenum pname, GLfloat *params)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateGetTexGenivOES(Context *context, GLenum coord, GLenum pname, int *params)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateGetTexGenxvOES(Context *context, GLenum coord, GLenum pname, GLfixed *params)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateTexGenfvOES(Context *context, GLenum coord, GLenum pname, const GLfloat *params)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateTexGenivOES(Context *context, GLenum coord, GLenum pname, const GLint *param)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateTexGenxvOES(Context *context, GLenum coord, GLenum pname, const GLint *param)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateTexGenfOES(Context *context, GLenum coord, GLenum pname, GLfloat param)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateTexGeniOES(Context *context, GLenum coord, GLenum pname, GLint param)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+
+bool ValidateTexGenxOES(Context *context, GLenum coord, GLenum pname, GLfixed param)
+{
+    UNIMPLEMENTED();
+    return true;
+}
+}
--- a/gfx/angle/checkout/src/libANGLE/validationES1.h
+++ b/gfx/angle/checkout/src/libANGLE/validationES1.h
@@ -13,18 +13,18 @@
 #include <GLES/glext.h>
 
 #include "libANGLE/validationES2.h"
 
 namespace gl
 {
 class Context;
 
-bool ValidateAlphaFunc(Context *context, GLenum func, GLfloat ref);
-bool ValidateAlphaFuncx(Context *context, GLenum func, GLfixed ref);
+bool ValidateAlphaFunc(Context *context, AlphaTestFunc func, GLfloat ref);
+bool ValidateAlphaFuncx(Context *context, AlphaTestFunc func, GLfixed ref);
 bool ValidateClearColorx(Context *context, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
 bool ValidateClearDepthx(Context *context, GLfixed depth);
 bool ValidateClientActiveTexture(Context *context, GLenum texture);
 bool ValidateClipPlanef(Context *context, GLenum p, const GLfloat *eqn);
 bool ValidateClipPlanex(Context *context, GLenum plane, const GLfixed *equation);
 bool ValidateColor4f(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
 bool ValidateColor4ub(Context *context, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
 bool ValidateColor4x(Context *context, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
@@ -62,17 +62,17 @@ bool ValidateGetFixedv(Context *context,
 bool ValidateGetLightfv(Context *context, GLenum light, GLenum pname, GLfloat *params);
 bool ValidateGetLightxv(Context *context, GLenum light, GLenum pname, GLfixed *params);
 bool ValidateGetMaterialfv(Context *context, GLenum face, GLenum pname, GLfloat *params);
 bool ValidateGetMaterialxv(Context *context, GLenum face, GLenum pname, GLfixed *params);
 bool ValidateGetPointerv(Context *context, GLenum pname, void **params);
 bool ValidateGetTexEnvfv(Context *context, GLenum target, GLenum pname, GLfloat *params);
 bool ValidateGetTexEnviv(Context *context, GLenum target, GLenum pname, GLint *params);
 bool ValidateGetTexEnvxv(Context *context, GLenum target, GLenum pname, GLfixed *params);
-bool ValidateGetTexParameterxv(Context *context, GLenum target, GLenum pname, GLfixed *params);
+bool ValidateGetTexParameterxv(Context *context, TextureType target, GLenum pname, GLfixed *params);
 bool ValidateLightModelf(Context *context, GLenum pname, GLfloat param);
 bool ValidateLightModelfv(Context *context, GLenum pname, const GLfloat *params);
 bool ValidateLightModelx(Context *context, GLenum pname, GLfixed param);
 bool ValidateLightModelxv(Context *context, GLenum pname, const GLfixed *param);
 bool ValidateLightf(Context *context, GLenum light, GLenum pname, GLfloat param);
 bool ValidateLightfv(Context *context, GLenum light, GLenum pname, const GLfloat *params);
 bool ValidateLightx(Context *context, GLenum light, GLenum pname, GLfixed param);
 bool ValidateLightxv(Context *context, GLenum light, GLenum pname, const GLfixed *params);
@@ -80,17 +80,17 @@ bool ValidateLineWidthx(Context *context
 bool ValidateLoadIdentity(Context *context);
 bool ValidateLoadMatrixf(Context *context, const GLfloat *m);
 bool ValidateLoadMatrixx(Context *context, const GLfixed *m);
 bool ValidateLogicOp(Context *context, GLenum opcode);
 bool ValidateMaterialf(Context *context, GLenum face, GLenum pname, GLfloat param);
 bool ValidateMaterialfv(Context *context, GLenum face, GLenum pname, const GLfloat *params);
 bool ValidateMaterialx(Context *context, GLenum face, GLenum pname, GLfixed param);
 bool ValidateMaterialxv(Context *context, GLenum face, GLenum pname, const GLfixed *param);
-bool ValidateMatrixMode(Context *context, GLenum mode);
+bool ValidateMatrixMode(Context *context, MatrixType mode);
 bool ValidateMultMatrixf(Context *context, const GLfloat *m);
 bool ValidateMultMatrixx(Context *context, const GLfixed *m);
 bool ValidateMultiTexCoord4f(Context *context,
                              GLenum target,
                              GLfloat s,
                              GLfloat t,
                              GLfloat r,
                              GLfloat q);
@@ -138,18 +138,21 @@ bool ValidateTexCoordPointer(Context *co
                              GLsizei stride,
                              const void *pointer);
 bool ValidateTexEnvf(Context *context, GLenum target, GLenum pname, GLfloat param);
 bool ValidateTexEnvfv(Context *context, GLenum target, GLenum pname, const GLfloat *params);
 bool ValidateTexEnvi(Context *context, GLenum target, GLenum pname, GLint param);
 bool ValidateTexEnviv(Context *context, GLenum target, GLenum pname, const GLint *params);
 bool ValidateTexEnvx(Context *context, GLenum target, GLenum pname, GLfixed param);
 bool ValidateTexEnvxv(Context *context, GLenum target, GLenum pname, const GLfixed *params);
-bool ValidateTexParameterx(Context *context, GLenum target, GLenum pname, GLfixed param);
-bool ValidateTexParameterxv(Context *context, GLenum target, GLenum pname, const GLfixed *params);
+bool ValidateTexParameterx(Context *context, TextureType target, GLenum pname, GLfixed param);
+bool ValidateTexParameterxv(Context *context,
+                            TextureType target,
+                            GLenum pname,
+                            const GLfixed *params);
 bool ValidateTranslatef(Context *context, GLfloat x, GLfloat y, GLfloat z);
 bool ValidateTranslatex(Context *context, GLfixed x, GLfixed y, GLfixed z);
 bool ValidateVertexPointer(Context *context,
                            GLint size,
                            GLenum type,
                            GLsizei stride,
                            const void *pointer);
 
@@ -195,11 +198,69 @@ bool ValidateWeightPointerOES(Context *c
 // GL_OES_point_size_array
 bool ValidatePointSizePointerOES(Context *context,
                                  GLenum type,
                                  GLsizei stride,
                                  const void *pointer);
 
 // GL_OES_query_matrix
 bool ValidateQueryMatrixxOES(Context *context, GLfixed *mantissa, GLint *exponent);
-}
+
+// GL_OES_framebuffer_object
+bool ValidateGenFramebuffersOES(Context *context, GLsizei n, GLuint *framebuffers);
+bool ValidateDeleteFramebuffersOES(Context *context, GLsizei n, const GLuint *framebuffers);
+
+bool ValidateGenRenderbuffersOES(Context *context, GLsizei n, GLuint *renderbuffers);
+bool ValidateDeleteRenderbuffersOES(Context *context, GLsizei n, const GLuint *renderbuffers);
+
+bool ValidateBindFramebufferOES(Context *context, GLenum target, GLuint framebuffer);
+bool ValidateBindRenderbufferOES(Context *context, GLenum target, GLuint renderbuffer);
+bool ValidateCheckFramebufferStatusOES(Context *context, GLenum target);
+bool ValidateFramebufferRenderbufferOES(Context *context,
+                                        GLenum target,
+                                        GLenum attachment,
+                                        GLenum rbtarget,
+                                        GLuint renderbuffer);
+bool ValidateFramebufferTexture2DOES(Context *context,
+                                     GLenum target,
+                                     GLenum attachment,
+                                     TextureTarget textarget,
+                                     GLuint texture,
+                                     GLint level);
+
+bool ValidateGenerateMipmapOES(Context *context, TextureType target);
+
+bool ValidateGetFramebufferAttachmentParameterivOES(Context *context,
+                                                    GLenum target,
+                                                    GLenum attachment,
+                                                    GLenum pname,
+                                                    GLint *params);
+
+bool ValidateGetRenderbufferParameterivOES(Context *context,
+                                           GLenum target,
+                                           GLenum pname,
+                                           GLint *params);
+
+bool ValidateIsFramebufferOES(Context *context, GLuint framebuffer);
+bool ValidateIsRenderbufferOES(Context *context, GLuint renderbuffer);
+
+bool ValidateRenderbufferStorageOES(Context *context,
+                                    GLenum target,
+                                    GLint internalformat,
+                                    GLsizei width,
+                                    GLsizei height);
+
+// GL_OES_texture_cube_map
+bool ValidateGetTexGenfvOES(Context *context, GLenum coord, GLenum pname, GLfloat *params);
+bool ValidateGetTexGenivOES(Context *context, GLenum coord, GLenum pname, int *params);
+bool ValidateGetTexGenxvOES(Context *context, GLenum coord, GLenum pname, GLfixed *params);
+
+bool ValidateTexGenfvOES(Context *context, GLenum coord, GLenum pname, const GLfloat *params);
+bool ValidateTexGenivOES(Context *context, GLenum coord, GLenum pname, const GLint *params);
+bool ValidateTexGenxvOES(Context *context, GLenum coord, GLenum pname, const GLfixed *params);
+
+bool ValidateTexGenfOES(Context *context, GLenum coord, GLenum pname, GLfloat param);
+bool ValidateTexGeniOES(Context *context, GLenum coord, GLenum pname, GLint param);
+bool ValidateTexGenxOES(Context *context, GLenum coord, GLenum pname, GLfixed param);
+
+}  // namespace gl
 
 #endif  // LIBANGLE_VALIDATION_ES1_H_
--- a/gfx/angle/checkout/src/libANGLE/validationES2.cpp
+++ b/gfx/angle/checkout/src/libANGLE/validationES2.cpp
@@ -70,17 +70,17 @@ bool ValidatePathInstances(gl::Context *
                            const void *paths,
                            GLuint pathBase)
 {
     const auto *array = static_cast<const T *>(paths);
 
     for (GLsizei i = 0; i < numPaths; ++i)
     {
         const GLuint pathName = array[i] + pathBase;
-        if (context->hasPath(pathName) && !context->hasPathData(pathName))
+        if (context->isPathGenerated(pathName) && !context->isPath(pathName))
         {
             ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
             return false;
         }
     }
     return true;
 }
 
@@ -302,120 +302,110 @@ bool IsValidCopyTextureDestinationFormat
     if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
     {
         return false;
     }
 
     return true;
 }
 
-bool IsValidCopyTextureDestinationTargetEnum(Context *context, GLenum target)
+bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
 {
     switch (target)
     {
-        case GL_TEXTURE_2D:
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+        case TextureTarget::_2D:
+        case TextureTarget::CubeMapNegativeX:
+        case TextureTarget::CubeMapNegativeY:
+        case TextureTarget::CubeMapNegativeZ:
+        case TextureTarget::CubeMapPositiveX:
+        case TextureTarget::CubeMapPositiveY:
+        case TextureTarget::CubeMapPositiveZ:
             return true;
 
-        case GL_TEXTURE_RECTANGLE_ANGLE:
+        case TextureTarget::Rectangle:
             return context->getExtensions().textureRectangle;
 
         default:
             return false;
     }
 }
 
-bool IsValidCopyTextureDestinationTarget(Context *context, GLenum textureType, GLenum target)
-{
-    if (IsCubeMapTextureTarget(target))
-    {
-        return textureType == GL_TEXTURE_CUBE_MAP;
-    }
-    else
-    {
-        return textureType == target;
-    }
-}
-
-bool IsValidCopyTextureSourceTarget(Context *context, GLenum target)
-{
-    switch (target)
-    {
-        case GL_TEXTURE_2D:
+bool IsValidCopyTextureDestinationTarget(Context *context,
+                                         TextureType textureType,
+                                         TextureTarget target)
+{
+    return TextureTargetToType(target) == textureType;
+}
+
+bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
+{
+    switch (type)
+    {
+        case TextureType::_2D:
             return true;
-        case GL_TEXTURE_RECTANGLE_ANGLE:
+        case TextureType::Rectangle:
             return context->getExtensions().textureRectangle;
 
         // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
         // supported
 
         default:
             return false;
     }
 }
 
-bool IsValidCopyTextureSourceLevel(Context *context, GLenum target, GLint level)
-{
-    if (!ValidMipLevel(context, target, level))
+bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
+{
+    if (!ValidMipLevel(context, type, level))
     {
         return false;
     }
 
     if (level > 0 && context->getClientVersion() < ES_3_0)
     {
         return false;
     }
 
     return true;
 }
 
 bool IsValidCopyTextureDestinationLevel(Context *context,
-                                        GLenum target,
+                                        TextureType type,
                                         GLint level,
                                         GLsizei width,
-                                        GLsizei height)
-{
-    if (!ValidMipLevel(context, target, level))
+                                        GLsizei height,
+                                        bool isSubImage)
+{
+    if (!ValidMipLevel(context, type, level))
+    {
+        return false;
+    }
+
+    if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
     {
         return false;
     }
 
     const Caps &caps = context->getCaps();
-    if (target == GL_TEXTURE_2D)
-    {
-        if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
-            static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
-        {
-            return false;
-        }
-    }
-    else if (target == GL_TEXTURE_RECTANGLE_ANGLE)
-    {
-        ASSERT(level == 0);
-        if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
-            static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
-        {
-            return false;
-        }
-    }
-    else if (IsCubeMapTextureTarget(target))
-    {
-        if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
-            static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
-        {
-            return false;
-        }
-    }
-
-    return true;
+    switch (type)
+    {
+        case TextureType::_2D:
+            return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
+                   static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
+        case TextureType::Rectangle:
+            ASSERT(level == 0);
+            return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
+                   static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
+
+        case TextureType::CubeMap:
+            return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
+                   static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
+        default:
+            return true;
+    }
 }
 
 bool IsValidStencilFunc(GLenum func)
 {
     switch (func)
     {
         case GL_NEVER:
         case GL_ALWAYS:
@@ -460,18 +450,18 @@ bool IsValidStencilOp(GLenum op)
         case GL_DECR_WRAP:
             return true;
 
         default:
             return false;
     }
 }
 
-bool ValidateES2CopyTexImageParameters(ValidationContext *context,
-                                       GLenum target,
+bool ValidateES2CopyTexImageParameters(Context *context,
+                                       TextureTarget target,
                                        GLint level,
                                        GLenum internalformat,
                                        bool isSubImage,
                                        GLint xoffset,
                                        GLint yoffset,
                                        GLint x,
                                        GLint y,
                                        GLsizei width,
@@ -479,17 +469,18 @@ bool ValidateES2CopyTexImageParameters(V
                                        GLint border)
 {
     if (!ValidTexture2DDestinationTarget(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
         return false;
     }
 
-    if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage))
+    TextureType texType = TextureTargetToType(target);
+    if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
     {
         context->handleError(InvalidValue() << "Invalid texture dimensions.");
         return false;
     }
 
     Format textureFormat = Format::Invalid();
     if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
                                             xoffset, yoffset, 0, x, y, width, height, border,
@@ -796,16 +787,20 @@ bool ValidCap(const Context *context, GL
             return context->getExtensions().sRGBWriteControl;
 
         case GL_SAMPLE_MASK:
             return context->getClientVersion() >= Version(3, 1);
 
         case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
             return queryOnly && context->getExtensions().robustResourceInitialization;
 
+        // GLES1 emulation: GLES1-specific caps
+        case GL_ALPHA_TEST:
+            return context->getClientVersion() < Version(2, 0);
+
         default:
             return false;
     }
 }
 
 // Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
 // 3.1.
 bool IsValidESSLCharacter(unsigned char c)
@@ -958,32 +953,32 @@ bool IsValidESSLShaderSourceString(const
                 pos++;
                 break;
         }
     }
 
     return true;
 }
 
-bool ValidateWebGLNamePrefix(ValidationContext *context, const GLchar *name)
+bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
 {
     ASSERT(context->isWebGL());
 
     // WebGL 1.0 [Section 6.16] GLSL Constructs
     // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
     if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
         return false;
     }
 
     return true;
 }
 
-bool ValidateWebGLNameLength(ValidationContext *context, size_t length)
+bool ValidateWebGLNameLength(Context *context, size_t length)
 {
     ASSERT(context->isWebGL());
 
     if (context->isWebGL1() && length > 256)
     {
         // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
         // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
         // locations.
@@ -1015,17 +1010,17 @@ bool ValidateMatrixMode(Context *context
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
         return false;
     }
     return true;
 }
 }  // anonymous namespace
 
 bool ValidateES2TexImageParameters(Context *context,
-                                   GLenum target,
+                                   TextureTarget target,
                                    GLint level,
                                    GLenum internalformat,
                                    bool isCompressed,
                                    bool isSubImage,
                                    GLint xoffset,
                                    GLint yoffset,
                                    GLsizei width,
                                    GLsizei height,
@@ -1036,23 +1031,24 @@ bool ValidateES2TexImageParameters(Conte
                                    const void *pixels)
 {
     if (!ValidTexture2DDestinationTarget(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
         return false;
     }
 
-    if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage))
+    TextureType texType = TextureTargetToType(target);
+    if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
     {
         context->handleError(InvalidValue());
         return false;
     }
 
-    if (!ValidMipLevel(context, target, level))
+    if (!ValidMipLevel(context, texType, level))
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
         return false;
     }
 
     if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
         std::numeric_limits<GLsizei>::max() - yoffset < height)
     {
@@ -1072,64 +1068,64 @@ bool ValidateES2TexImageParameters(Conte
     if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
     {
         context->handleError(InvalidOperation());
         return false;
     }
 
     const gl::Caps &caps = context->getCaps();
 
-    if (target == GL_TEXTURE_2D)
-    {
-        if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
-            static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
-        {
-            context->handleError(InvalidValue());
-            return false;
-        }
-    }
-    else if (target == GL_TEXTURE_RECTANGLE_ANGLE)
-    {
-        ASSERT(level == 0);
-        if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
-            static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
-        {
-            context->handleError(InvalidValue());
-            return false;
-        }
-        if (isCompressed)
-        {
-            context->handleError(InvalidEnum()
-                                 << "Rectangle texture cannot have a compressed format.");
+    switch (texType)
+    {
+        case TextureType::_2D:
+            if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
+                static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
+            {
+                context->handleError(InvalidValue());
+                return false;
+            }
+            break;
+
+        case TextureType::Rectangle:
+            ASSERT(level == 0);
+            if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
+                static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
+            {
+                context->handleError(InvalidValue());
+                return false;
+            }
+            if (isCompressed)
+            {
+                context->handleError(InvalidEnum()
+                                     << "Rectangle texture cannot have a compressed format.");
+                return false;
+            }
+            break;
+
+        case TextureType::CubeMap:
+            if (!isSubImage && width != height)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
+                return false;
+            }
+
+            if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
+                static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
+            {
+                context->handleError(InvalidValue());
+                return false;
+            }
+            break;
+
+        default:
+            context->handleError(InvalidEnum());
             return false;
-        }
-    }
-    else if (IsCubeMapTextureTarget(target))
-    {
-        if (!isSubImage && width != height)
-        {
-            ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
-            return false;
-        }
-
-        if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
-            static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
-        {
-            context->handleError(InvalidValue());
-            return false;
-        }
-    }
-    else
-    {
-        context->handleError(InvalidEnum());
-        return false;
-    }
-
-    gl::Texture *texture =
-        context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+    }
+
+    gl::Texture *texture = context->getTargetTexture(texType);
     if (!texture)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
         return false;
     }
 
     if (isSubImage)
     {
@@ -1153,17 +1149,17 @@ bool ValidateES2TexImageParameters(Conte
         if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
             static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
         {
             context->handleError(InvalidValue());
             return false;
         }
 
         if (width > 0 && height > 0 && pixels == nullptr &&
-            context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack) == nullptr)
+            context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
         {
             ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
             return false;
         }
     }
     else
     {
         if (texture->getImmutableFormat())
@@ -1496,17 +1492,17 @@ bool ValidateES2TexImageParameters(Conte
                 break;
             case GL_DEPTH_COMPONENT:
             case GL_DEPTH_STENCIL_OES:
                 if (!context->getExtensions().depthTextures)
                 {
                     context->handleError(InvalidValue());
                     return false;
                 }
-                if (target != GL_TEXTURE_2D)
+                if (target != TextureTarget::_2D)
                 {
                     ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
                     return false;
                 }
                 // OES_depth_texture supports loading depth data and multiple levels,
                 // but ANGLE_depth_texture does not
                 if (pixels != nullptr)
                 {
@@ -1586,46 +1582,46 @@ bool ValidateES2TexImageParameters(Conte
             {
                 context->handleError(InvalidEnum());
                 return false;
             }
         }
     }
 
     GLenum sizeCheckFormat = isSubImage ? format : internalformat;
-    if (!ValidImageDataSize(context, target, width, height, 1, sizeCheckFormat, type, pixels,
+    if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
                             imageSize))
     {
         return false;
     }
 
     return true;
 }
 
 bool ValidateES2TexStorageParameters(Context *context,
-                                     GLenum target,
+                                     TextureType target,
                                      GLsizei levels,
                                      GLenum internalformat,
                                      GLsizei width,
                                      GLsizei height)
 {
-    if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP &&
-        target != GL_TEXTURE_RECTANGLE_ANGLE)
+    if (target != TextureType::_2D && target != TextureType::CubeMap &&
+        target != TextureType::Rectangle)
     {
         context->handleError(InvalidEnum());
         return false;
     }
 
     if (width < 1 || height < 1 || levels < 1)
     {
         context->handleError(InvalidValue());
         return false;
     }
 
-    if (target == GL_TEXTURE_CUBE_MAP && width != height)
+    if (target == TextureType::CubeMap && width != height)
     {
         context->handleError(InvalidValue());
         return false;
     }
 
     if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
     {
         context->handleError(InvalidOperation());
@@ -1638,39 +1634,39 @@ bool ValidateES2TexStorageParameters(Con
         context->handleError(InvalidEnum());
         return false;
     }
 
     const gl::Caps &caps = context->getCaps();
 
     switch (target)
     {
-        case GL_TEXTURE_2D:
+        case TextureType::_2D:
             if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
                 static_cast<GLuint>(height) > caps.max2DTextureSize)
             {
                 context->handleError(InvalidValue());
                 return false;
             }
             break;
-        case GL_TEXTURE_RECTANGLE_ANGLE:
+        case TextureType::Rectangle:
             if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
                 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
             {
                 context->handleError(InvalidValue());
                 return false;
             }
             if (formatInfo.compressed)
             {
                 context->handleError(InvalidEnum()
                                      << "Rectangle texture cannot have a compressed format.");
                 return false;
             }
             break;
-        case GL_TEXTURE_CUBE_MAP:
+        case TextureType::CubeMap:
             if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
                 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
             {
                 context->handleError(InvalidValue());
                 return false;
             }
             break;
         default:
@@ -1779,17 +1775,17 @@ bool ValidateES2TexStorageParameters(Con
         case GL_DEPTH_COMPONENT16:
         case GL_DEPTH_COMPONENT32_OES:
         case GL_DEPTH24_STENCIL8_OES:
             if (!context->getExtensions().depthTextures)
             {
                 context->handleError(InvalidEnum());
                 return false;
             }
-            if (target != GL_TEXTURE_2D)
+            if (target != TextureType::_2D)
             {
                 context->handleError(InvalidOperation());
                 return false;
             }
             // ANGLE_depth_texture only supports 1-level textures
             if (levels != 1)
             {
                 context->handleError(InvalidOperation());
@@ -2418,16 +2414,26 @@ bool ValidateGetPointervKHR(Context *con
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
             return false;
     }
 
     return true;
 }
 
+bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
+                                               GLenum pname,
+                                               GLsizei bufSize,
+                                               GLsizei *length,
+                                               void **params)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
 bool ValidateBlitFramebufferANGLE(Context *context,
                                   GLint srcX0,
                                   GLint srcY0,
                                   GLint srcX1,
                                   GLint srcY1,
                                   GLint dstX0,
                                   GLint dstY0,
                                   GLint dstX1,
@@ -2462,33 +2468,33 @@ bool ValidateBlitFramebufferANGLE(Contex
     if (mask & GL_COLOR_BUFFER_BIT)
     {
         const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
         const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
 
         if (readColorAttachment && drawColorAttachment)
         {
             if (!(readColorAttachment->type() == GL_TEXTURE &&
-                  readColorAttachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
+                  readColorAttachment->getTextureImageIndex().type == TextureType::_2D) &&
                 readColorAttachment->type() != GL_RENDERBUFFER &&
                 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
             {
                 context->handleError(InvalidOperation());
                 return false;
             }
 
             for (size_t drawbufferIdx = 0;
                  drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
             {
                 const FramebufferAttachment *attachment =
                     drawFramebuffer->getDrawBuffer(drawbufferIdx);
                 if (attachment)
                 {
                     if (!(attachment->type() == GL_TEXTURE &&
-                          attachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
+                          attachment->getTextureImageIndex().type == TextureType::_2D) &&
                         attachment->type() != GL_RENDERBUFFER &&
                         attachment->type() != GL_FRAMEBUFFER_DEFAULT)
                     {
                         context->handleError(InvalidOperation());
                         return false;
                     }
 
                     // Return an error if the destination formats do not match
@@ -2496,17 +2502,19 @@ bool ValidateBlitFramebufferANGLE(Contex
                                                    readColorAttachment->getFormat()))
                     {
                         context->handleError(InvalidOperation());
                         return false;
                     }
                 }
             }
 
-            if (readFramebuffer->getSamples(context) != 0 &&
+            GLint samples = 0;
+            ANGLE_VALIDATION_TRY(readFramebuffer->getSamples(context, &samples));
+            if (samples != 0 &&
                 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
                               srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
             {
                 context->handleError(InvalidOperation());
                 return false;
             }
         }
     }
@@ -2542,22 +2550,22 @@ bool ValidateBlitFramebufferANGLE(Contex
             }
         }
     }
 
     return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
                                              dstX1, dstY1, mask, filter);
 }
 
-bool ValidateClear(ValidationContext *context, GLbitfield mask)
+bool ValidateClear(Context *context, GLbitfield mask)
 {
     Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
-    if (fbo->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
-    {
-        context->handleError(InvalidFramebufferOperation());
+
+    if (!ValidateFramebufferComplete(context, fbo, true))
+    {
         return false;
     }
 
     if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
         return false;
     }
@@ -2576,29 +2584,29 @@ bool ValidateClear(ValidationContext *co
                 return false;
             }
         }
     }
 
     return true;
 }
 
-bool ValidateDrawBuffersEXT(ValidationContext *context, GLsizei n, const GLenum *bufs)
+bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
 {
     if (!context->getExtensions().drawBuffers)
     {
         context->handleError(InvalidOperation() << "Extension not supported.");
         return false;
     }
 
     return ValidateDrawBuffersBase(context, n, bufs);
 }
 
 bool ValidateTexImage2D(Context *context,
-                        GLenum target,
+                        TextureTarget target,
                         GLint level,
                         GLint internalformat,
                         GLsizei width,
                         GLsizei height,
                         GLint border,
                         GLenum format,
                         GLenum type,
                         const void *pixels)
@@ -2611,17 +2619,17 @@ bool ValidateTexImage2D(Context *context
 
     ASSERT(context->getClientMajorVersion() >= 3);
     return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
                                            0, 0, width, height, 1, border, format, type, -1,
                                            pixels);
 }
 
 bool ValidateTexImage2DRobust(Context *context,
-                              GLenum target,
+                              TextureTarget target,
                               GLint level,
                               GLint internalformat,
                               GLsizei width,
                               GLsizei height,
                               GLint border,
                               GLenum format,
                               GLenum type,
                               GLsizei bufSize,
@@ -2641,17 +2649,17 @@ bool ValidateTexImage2DRobust(Context *c
 
     ASSERT(context->getClientMajorVersion() >= 3);
     return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
                                            0, 0, width, height, 1, border, format, type, bufSize,
                                            pixels);
 }
 
 bool ValidateTexSubImage2D(Context *context,
-                           GLenum target,
+                           TextureTarget target,
                            GLint level,
                            GLint xoffset,
                            GLint yoffset,
                            GLsizei width,
                            GLsizei height,
                            GLenum format,
                            GLenum type,
                            const void *pixels)
@@ -2665,17 +2673,17 @@ bool ValidateTexSubImage2D(Context *cont
 
     ASSERT(context->getClientMajorVersion() >= 3);
     return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
                                            yoffset, 0, width, height, 1, 0, format, type, -1,
                                            pixels);
 }
 
 bool ValidateTexSubImage2DRobustANGLE(Context *context,
-                                      GLenum target,
+                                      TextureTarget target,
                                       GLint level,
                                       GLint xoffset,
                                       GLint yoffset,
                                       GLsizei width,
                                       GLsizei height,
                                       GLenum format,
                                       GLenum type,
                                       GLsizei bufSize,
@@ -2695,17 +2703,17 @@ bool ValidateTexSubImage2DRobustANGLE(Co
 
     ASSERT(context->getClientMajorVersion() >= 3);
     return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
                                            yoffset, 0, width, height, 1, 0, format, type, bufSize,
                                            pixels);
 }
 
 bool ValidateCompressedTexImage2D(Context *context,
-                                  GLenum target,
+                                  TextureTarget target,
                                   GLint level,
                                   GLenum internalformat,
                                   GLsizei width,
                                   GLsizei height,
                                   GLint border,
                                   GLsizei imageSize,
                                   const void *data)
 {
@@ -2737,27 +2745,27 @@ bool ValidateCompressedTexImage2D(Contex
     }
 
     if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
         return false;
     }
 
-    if (target == GL_TEXTURE_RECTANGLE_ANGLE)
+    if (target == TextureTarget::Rectangle)
     {
         context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
         return false;
     }
 
     return true;
 }
 
 bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
-                                             GLenum target,
+                                             TextureTarget target,
                                              GLint level,
                                              GLenum internalformat,
                                              GLsizei width,
                                              GLsizei height,
                                              GLint border,
                                              GLsizei imageSize,
                                              GLsizei dataSize,
                                              const void *data)
@@ -2765,18 +2773,19 @@ bool ValidateCompressedTexImage2DRobustA
     if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
     {
         return false;
     }
 
     return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
                                         border, imageSize, data);
 }
+
 bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
-                                                GLenum target,
+                                                TextureTarget target,
                                                 GLint level,
                                                 GLint xoffset,
                                                 GLint yoffset,
                                                 GLsizei width,
                                                 GLsizei height,
                                                 GLenum format,
                                                 GLsizei imageSize,
                                                 GLsizei dataSize,
@@ -2787,17 +2796,17 @@ bool ValidateCompressedTexSubImage2DRobu
         return false;
     }
 
     return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
                                            format, imageSize, data);
 }
 
 bool ValidateCompressedTexSubImage2D(Context *context,
-                                     GLenum target,
+                                     TextureTarget target,
                                      GLint level,
                                      GLint xoffset,
                                      GLint yoffset,
                                      GLsizei width,
                                      GLsizei height,
                                      GLenum format,
                                      GLsizei imageSize,
                                      const void *data)
@@ -2925,16 +2934,23 @@ bool ValidateMapBufferBase(Context *cont
             {
                 context->handleError(InvalidOperation()
                                      << "Buffer is currently bound for transform feedback.");
                 return false;
             }
         }
     }
 
+    if (context->getExtensions().webglCompatibility &&
+        buffer->isBoundForTransformFeedbackAndOtherUse())
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
+        return false;
+    }
+
     return true;
 }
 
 bool ValidateFlushMappedBufferRangeEXT(Context *context,
                                        BufferBinding target,
                                        GLintptr offset,
                                        GLsizeiptr length)
 {
@@ -2942,65 +2958,65 @@ bool ValidateFlushMappedBufferRangeEXT(C
     {
         context->handleError(InvalidOperation() << "Map buffer range extension not available.");
         return false;
     }
 
     return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
 }
 
-bool ValidateBindTexture(Context *context, GLenum target, GLuint texture)
+bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
 {
     Texture *textureObject = context->getTexture(texture);
-    if (textureObject && textureObject->getTarget() != target && texture != 0)
+    if (textureObject && textureObject->getType() != target && texture != 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
         return false;
     }
 
     if (!context->getGLState().isBindGeneratesResourceEnabled() &&
         !context->isTextureGenerated(texture))
     {
         context->handleError(InvalidOperation() << "Texture was not generated");
         return false;
     }
 
     switch (target)
     {
-        case GL_TEXTURE_2D:
-        case GL_TEXTURE_CUBE_MAP:
+        case TextureType::_2D:
+        case TextureType::CubeMap:
             break;
 
-        case GL_TEXTURE_RECTANGLE_ANGLE:
+        case TextureType::Rectangle:
             if (!context->getExtensions().textureRectangle)
             {
                 context->handleError(InvalidEnum()
                                      << "Context does not support GL_ANGLE_texture_rectangle");
                 return false;
             }
             break;
 
-        case GL_TEXTURE_3D:
-        case GL_TEXTURE_2D_ARRAY:
+        case TextureType::_3D:
+        case TextureType::_2DArray:
             if (context->getClientMajorVersion() < 3)
             {
                 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
                 return false;
             }
             break;
 
-        case GL_TEXTURE_2D_MULTISAMPLE:
+        case TextureType::_2DMultisample:
             if (context->getClientVersion() < Version(3, 1))
             {
                 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
                 return false;
             }
             break;
 
-        case GL_TEXTURE_EXTERNAL_OES:
+        case TextureType::External:
             if (!context->getExtensions().eglImageExternal &&
                 !context->getExtensions().eglStreamConsumerExternal)
             {
                 context->handleError(InvalidEnum() << "External texture extension not enabled");
                 return false;
             }
             break;
         default:
@@ -3170,17 +3186,17 @@ bool ValidatePathCommandsCHROMIUM(Contex
                                   GLenum coordType,
                                   const void *coords)
 {
     if (!context->getExtensions().pathRendering)
     {
         context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
         return false;
     }
-    if (!context->hasPath(path))
+    if (!context->isPathGenerated(path))
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
         return false;
     }
 
     if (numCommands < 0)
     {
         context->handleError(InvalidValue() << "Invalid number of commands.");
@@ -3285,17 +3301,17 @@ bool ValidatePathCommandsCHROMIUM(Contex
 
 bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
 {
     if (!context->getExtensions().pathRendering)
     {
         context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
         return false;
     }
-    if (!context->hasPath(path))
+    if (!context->isPathGenerated(path))
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
         return false;
     }
 
     switch (pname)
     {
         case GL_PATH_STROKE_WIDTH_CHROMIUM:
@@ -3357,17 +3373,17 @@ bool ValidatePathParameteriCHROMIUM(Cont
 bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
 {
     if (!context->getExtensions().pathRendering)
     {
         context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
         return false;
     }
 
-    if (!context->hasPath(path))
+    if (!context->isPathGenerated(path))
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
         return false;
     }
     if (!value)
     {
         context->handleError(InvalidValue() << "No value array.");
         return false;
@@ -3431,17 +3447,17 @@ bool ValidatePathStencilFuncCHROMIUM(Con
 
 bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
 {
     if (!context->getExtensions().pathRendering)
     {
         context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
         return false;
     }
-    if (context->hasPath(path) && !context->hasPathData(path))
+    if (context->isPathGenerated(path) && !context->isPath(path))
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
         return false;
     }
 
     switch (fillMode)
     {
         case GL_COUNT_UP_CHROMIUM:
@@ -3463,33 +3479,43 @@ bool ValidateStencilFillPathCHROMIUM(Con
 
 bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
 {
     if (!context->getExtensions().pathRendering)
     {
         context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
         return false;
     }
-    if (context->hasPath(path) && !context->hasPathData(path))
+    if (context->isPathGenerated(path) && !context->isPath(path))
     {
         context->handleError(InvalidOperation() << "No such path or path has no data.");
         return false;
     }
 
     return true;
 }
 
+bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
+{
+    return ValidateCoverPathCHROMIUM(context, path, coverMode);
+}
+
+bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
+{
+    return ValidateCoverPathCHROMIUM(context, path, coverMode);
+}
+
 bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
 {
     if (!context->getExtensions().pathRendering)
     {
         context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
         return false;
     }
-    if (context->hasPath(path) && !context->hasPathData(path))
+    if (context->isPathGenerated(path) && !context->isPath(path))
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
         return false;
     }
 
     switch (coverMode)
     {
         case GL_CONVEX_HULL_CHROMIUM:
@@ -3517,17 +3543,17 @@ bool ValidateStencilThenCoverStrokePathC
                                                 GLint reference,
                                                 GLuint mask,
                                                 GLenum coverMode)
 {
     return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
            ValidateCoverPathCHROMIUM(context, path, coverMode);
 }
 
-bool ValidateIsPathCHROMIUM(Context *context)
+bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
 {
     if (!context->getExtensions().pathRendering)
     {
         context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
         return false;
     }
     return true;
 }
@@ -3849,17 +3875,17 @@ bool ValidateProgramPathFragmentInputGen
         }
     }
     return true;
 }
 
 bool ValidateCopyTextureCHROMIUM(Context *context,
                                  GLuint sourceId,
                                  GLint sourceLevel,
-                                 GLenum destTarget,
+                                 TextureTarget destTarget,
                                  GLuint destId,
                                  GLint destLevel,
                                  GLint internalFormat,
                                  GLenum destType,
                                  GLboolean unpackFlipY,
                                  GLboolean unpackPremultiplyAlpha,
                                  GLboolean unpackUnmultiplyAlpha)
 {
@@ -3872,26 +3898,27 @@ bool ValidateCopyTextureCHROMIUM(Context
 
     const Texture *source = context->getTexture(sourceId);
     if (source == nullptr)
     {
         context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
         return false;
     }
 
-    if (!IsValidCopyTextureSourceTarget(context, source->getTarget()))
+    if (!IsValidCopyTextureSourceTarget(context, source->getType()))
     {
         context->handleError(InvalidValue() << "Source texture a valid texture type.");
         return false;
     }
 
-    GLenum sourceTarget = source->getTarget();
-    ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP);
-
-    if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel))
+    TextureType sourceType = source->getType();
+    ASSERT(sourceType != TextureType::CubeMap);
+    TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
+
+    if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
     {
         context->handleError(InvalidValue() << "Source texture level is not valid.");
         return false;
     }
 
     GLsizei sourceWidth  = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
     GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
     if (sourceWidth == 0 || sourceHeight == 0)
@@ -3916,36 +3943,36 @@ bool ValidateCopyTextureCHROMIUM(Context
     const Texture *dest = context->getTexture(destId);
     if (dest == nullptr)
     {
         context->handleError(InvalidValue()
                              << "Destination texture is not a valid texture object.");
         return false;
     }
 
-    if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget))
+    if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
     {
         context->handleError(InvalidValue() << "Destination texture a valid texture type.");
         return false;
     }
 
-    if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, sourceWidth,
-                                            sourceHeight))
+    if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
+                                            sourceHeight, false))
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
         return false;
     }
 
     if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
         return false;
     }
 
-    if (IsCubeMapTextureTarget(destTarget) && sourceWidth != sourceHeight)
+    if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
     {
         context->handleError(
             InvalidValue() << "Destination width and height must be equal for cube map textures.");
         return false;
     }
 
     if (dest->getImmutableFormat())
     {
@@ -3954,17 +3981,17 @@ bool ValidateCopyTextureCHROMIUM(Context
     }
 
     return true;
 }
 
 bool ValidateCopySubTextureCHROMIUM(Context *context,
                                     GLuint sourceId,
                                     GLint sourceLevel,
-                                    GLenum destTarget,
+                                    TextureTarget destTarget,
                                     GLuint destId,
                                     GLint destLevel,
                                     GLint xoffset,
                                     GLint yoffset,
                                     GLint x,
                                     GLint y,
                                     GLsizei width,
                                     GLsizei height,
@@ -3981,26 +4008,27 @@ bool ValidateCopySubTextureCHROMIUM(Cont
 
     const Texture *source = context->getTexture(sourceId);
     if (source == nullptr)
     {
         context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
         return false;
     }
 
-    if (!IsValidCopyTextureSourceTarget(context, source->getTarget()))
+    if (!IsValidCopyTextureSourceTarget(context, source->getType()))
     {
         context->handleError(InvalidValue() << "Source texture a valid texture type.");
         return false;
     }
 
-    GLenum sourceTarget = source->getTarget();
-    ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP);
-
-    if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel))
+    TextureType sourceType = source->getType();
+    ASSERT(sourceType != TextureType::CubeMap);
+    TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
+
+    if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
         return false;
     }
 
     if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
         source->getHeight(sourceTarget, sourceLevel) == 0)
     {
@@ -4044,23 +4072,24 @@ bool ValidateCopySubTextureCHROMIUM(Cont
     const Texture *dest = context->getTexture(destId);
     if (dest == nullptr)
     {
         context->handleError(InvalidValue()
                              << "Destination texture is not a valid texture object.");
         return false;
     }
 
-    if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget))
+    if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
     {
         context->handleError(InvalidValue() << "Destination texture a valid texture type.");
         return false;
     }
 
-    if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, width, height))
+    if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
+                                            true))
     {
         context->handleError(InvalidValue() << "Destination texture level is not valid.");
         return false;
     }
 
     if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
     {
         context
@@ -4104,92 +4133,93 @@ bool ValidateCompressedCopyTextureCHROMI
 
     const gl::Texture *source = context->getTexture(sourceId);
     if (source == nullptr)
     {
         context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
         return false;
     }
 
-    if (source->getTarget() != GL_TEXTURE_2D)
+    if (source->getType() != TextureType::_2D)
     {
         context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
         return false;
     }
 
-    if (source->getWidth(GL_TEXTURE_2D, 0) == 0 || source->getHeight(GL_TEXTURE_2D, 0) == 0)
+    if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
+        source->getHeight(TextureTarget::_2D, 0) == 0)
     {
         context->handleError(InvalidValue() << "Source texture must level 0 defined.");
         return false;
     }
 
-    const gl::Format &sourceFormat = source->getFormat(GL_TEXTURE_2D, 0);
+    const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
     if (!sourceFormat.info->compressed)
     {
         context->handleError(InvalidOperation()
                              << "Source texture must have a compressed internal format.");
         return false;
     }
 
     const gl::Texture *dest = context->getTexture(destId);
     if (dest == nullptr)
     {
         context->handleError(InvalidValue()
                              << "Destination texture is not a valid texture object.");
         return false;
     }
 
-    if (dest->getTarget() != GL_TEXTURE_2D)
+    if (dest->getType() != TextureType::_2D)
     {
         context->handleError(InvalidValue()
                              << "Destination texture must be of type GL_TEXTURE_2D.");
         return false;
     }
 
     if (dest->getImmutableFormat())
     {
         context->handleError(InvalidOperation() << "Destination cannot be immutable.");
         return false;
     }
 
     return true;
 }
 
-bool ValidateCreateShader(Context *context, GLenum type)
+bool ValidateCreateShader(Context *context, ShaderType type)
 {
     switch (type)
     {
-        case GL_VERTEX_SHADER:
-        case GL_FRAGMENT_SHADER:
+        case ShaderType::Vertex:
+        case ShaderType::Fragment:
             break;
 
-        case GL_COMPUTE_SHADER:
+        case ShaderType::Compute:
             if (context->getClientVersion() < Version(3, 1))
             {
                 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
                 return false;
             }
             break;
 
-        case GL_GEOMETRY_SHADER_EXT:
+        case ShaderType::Geometry:
             if (!context->getExtensions().geometryShader)
             {
                 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
                 return false;
             }
             break;
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
             return false;
     }
 
     return true;
 }
 
-bool ValidateBufferData(ValidationContext *context,
+bool ValidateBufferData(Context *context,
                         BufferBinding target,
                         GLsizeiptr size,
                         const void *data,
                         BufferUsage usage)
 {
     if (size < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
@@ -4230,20 +4260,27 @@ bool ValidateBufferData(ValidationContex
     Buffer *buffer = context->getGLState().getTargetBuffer(target);
 
     if (!buffer)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
         return false;
     }
 
+    if (context->getExtensions().webglCompatibility &&
+        buffer->isBoundForTransformFeedbackAndOtherUse())
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
+        return false;
+    }
+
     return true;
 }
 
-bool ValidateBufferSubData(ValidationContext *context,
+bool ValidateBufferSubData(Context *context,
                            BufferBinding target,
                            GLintptr offset,
                            GLsizeiptr size,
                            const void *data)
 {
     if (size < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
@@ -4271,16 +4308,23 @@ bool ValidateBufferSubData(ValidationCon
     }
 
     if (buffer->isMapped())
     {
         context->handleError(InvalidOperation());
         return false;
     }
 
+    if (context->getExtensions().webglCompatibility &&
+        buffer->isBoundForTransformFeedbackAndOtherUse())
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
+        return false;
+    }
+
     // Check for possible overflow of size + offset
     angle::CheckedNumeric<size_t> checkedSize(size);
     checkedSize += offset;
     if (!checkedSize.IsValid())
     {
         context->handleError(OutOfMemory());
         return false;
     }
@@ -4306,92 +4350,57 @@ bool ValidateRequestExtensionANGLE(Conte
     {
         context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
         return false;
     }
 
     return true;
 }
 
-bool ValidateActiveTexture(ValidationContext *context, GLenum texture)
-{
+bool ValidateActiveTexture(Context *context, GLenum texture)
+{
+    if (context->getClientMajorVersion() < 2)
+    {
+        return ValidateMultitextureUnit(context, texture);
+    }
+
     if (texture < GL_TEXTURE0 ||
         texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
     {
-        context->handleError(InvalidEnum());
+        ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
         return false;
     }
 
     return true;
 }
 
-bool ValidateAttachShader(ValidationContext *context, GLuint program, GLuint shader)
+bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
 {
     Program *programObject = GetValidProgram(context, program);
     if (!programObject)
     {
         return false;
     }
 
     Shader *shaderObject = GetValidShader(context, shader);
     if (!shaderObject)
     {
         return false;
     }
 
-    switch (shaderObject->getType())
-    {
-        case GL_VERTEX_SHADER:
-        {
-            if (programObject->getAttachedVertexShader())
-            {
-                ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
-                return false;
-            }
-            break;
-        }
-        case GL_FRAGMENT_SHADER:
-        {
-            if (programObject->getAttachedFragmentShader())
-            {
-                ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
-                return false;
-            }
-            break;
-        }
-        case GL_COMPUTE_SHADER:
-        {
-            if (programObject->getAttachedComputeShader())
-            {
-                ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
-                return false;
-            }
-            break;
-        }
-        case GL_GEOMETRY_SHADER_EXT:
-        {
-            if (programObject->getAttachedGeometryShader())
-            {
-                ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
-                return false;
-            }
-            break;
-        }
-        default:
-            UNREACHABLE();
-            break;
+    if (programObject->getAttachedShader(shaderObject->getType()))
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
+        return false;
     }
 
     return true;
 }
 
-bool ValidateBindAttribLocation(ValidationContext *context,
-                                GLuint program,
-                                GLuint index,
-                                const GLchar *name)
+bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
 {
     if (index >= MAX_VERTEX_ATTRIBS)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
         return false;
     }
 
     if (strncmp(name, "gl_", 3) == 0)
@@ -4416,17 +4425,17 @@ bool ValidateBindAttribLocation(Validati
         {
             return false;
         }
     }
 
     return GetValidProgram(context, program) != nullptr;
 }
 
-bool ValidateBindBuffer(ValidationContext *context, BufferBinding target, GLuint buffer)
+bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
 {
     if (!context->isValidBufferBinding(target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
         return false;
     }
 
     if (!context->getGLState().isBindGeneratesResourceEnabled() &&
@@ -4434,17 +4443,17 @@ bool ValidateBindBuffer(ValidationContex
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
         return false;
     }
 
     return true;
 }
 
-bool ValidateBindFramebuffer(ValidationContext *context, GLenum target, GLuint framebuffer)
+bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
 {
     if (!ValidFramebufferTarget(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
         return false;
     }
 
     if (!context->getGLState().isBindGeneratesResourceEnabled() &&
@@ -4452,17 +4461,17 @@ bool ValidateBindFramebuffer(ValidationC
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
         return false;
     }
 
     return true;
 }
 
-bool ValidateBindRenderbuffer(ValidationContext *context, GLenum target, GLuint renderbuffer)
+bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
 {
     if (target != GL_RENDERBUFFER)
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
         return false;
     }
 
     if (!context->getGLState().isBindGeneratesResourceEnabled() &&
@@ -4470,17 +4479,17 @@ bool ValidateBindRenderbuffer(Validation
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
         return false;
     }
 
     return true;
 }
 
-static bool ValidBlendEquationMode(const ValidationContext *context, GLenum mode)
+static bool ValidBlendEquationMode(const Context *context, GLenum mode)
 {
     switch (mode)
     {
         case GL_FUNC_ADD:
         case GL_FUNC_SUBTRACT:
         case GL_FUNC_REVERSE_SUBTRACT:
             return true;
 
@@ -4488,54 +4497,50 @@ static bool ValidBlendEquationMode(const
         case GL_MAX:
             return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
 
         default:
             return false;
     }
 }
 
-bool ValidateBlendColor(ValidationContext *context,
-                        GLfloat red,
-                        GLfloat green,
-                        GLfloat blue,
-                        GLfloat alpha)
+bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
 {
     return true;
 }
 
-bool ValidateBlendEquation(ValidationContext *context, GLenum mode)
+bool ValidateBlendEquation(Context *context, GLenum mode)
 {
     if (!ValidBlendEquationMode(context, mode))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
         return false;
     }
 
     return true;
 }
 
-bool ValidateBlendEquationSeparate(ValidationContext *context, GLenum modeRGB, GLenum modeAlpha)
+bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
 {
     if (!ValidBlendEquationMode(context, modeRGB))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
         return false;
     }
 
     if (!ValidBlendEquationMode(context, modeAlpha))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
         return false;
     }
 
     return true;
 }
 
-bool ValidateBlendFunc(ValidationContext *context, GLenum sfactor, GLenum dfactor)
+bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
 {
     return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
 }
 
 static bool ValidSrcBlendFunc(GLenum srcBlend)
 {
     switch (srcBlend)
     {
@@ -4584,17 +4589,17 @@ static bool ValidDstBlendFunc(GLenum dst
         case GL_SRC_ALPHA_SATURATE:
             return (contextMajorVersion >= 3);
 
         default:
             return false;
     }
 }
 
-bool ValidateBlendFuncSeparate(ValidationContext *context,
+bool ValidateBlendFuncSeparate(Context *context,
                                GLenum srcRGB,
                                GLenum dstRGB,
                                GLenum srcAlpha,
                                GLenum dstAlpha)
 {
     if (!ValidSrcBlendFunc(srcRGB))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
@@ -4675,28 +4680,28 @@ bool ValidateGetString(Context *context,
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
             return false;
     }
 
     return true;
 }
 
-bool ValidateLineWidth(ValidationContext *context, GLfloat width)
+bool ValidateLineWidth(Context *context, GLfloat width)
 {
     if (width <= 0.0f || isNaN(width))
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
         return false;
     }
 
     return true;
 }
 
-bool ValidateVertexAttribPointer(ValidationContext *context,
+bool ValidateVertexAttribPointer(Context *context,
                                  GLuint index,
                                  GLint size,
                                  GLenum type,
                                  GLboolean normalized,
                                  GLsizei stride,
                                  const void *ptr)
 {
     if (!ValidateVertexFormatBase(context, index, size, type, false))
@@ -4757,38 +4762,38 @@ bool ValidateVertexAttribPointer(Validat
         {
             return false;
         }
     }
 
     return true;
 }
 
-bool ValidateDepthRangef(ValidationContext *context, GLfloat zNear, GLfloat zFar)
+bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
 {
     if (context->getExtensions().webglCompatibility && zNear > zFar)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
         return false;
     }
 
     return true;
 }
 
-bool ValidateRenderbufferStorage(ValidationContext *context,
+bool ValidateRenderbufferStorage(Context *context,
                                  GLenum target,
                                  GLenum internalformat,
                                  GLsizei width,
                                  GLsizei height)
 {
     return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
                                                      height);
 }
 
-bool ValidateRenderbufferStorageMultisampleANGLE(ValidationContext *context,
+bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
                                                  GLenum target,
                                                  GLsizei samples,
                                                  GLenum internalformat,
                                                  GLsizei width,
                                                  GLsizei height)
 {
     if (!context->getExtensions().framebufferMultisample)
     {
@@ -4819,83 +4824,79 @@ bool ValidateRenderbufferStorageMultisam
             return false;
         }
     }
 
     return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
                                                      width, height);
 }
 
-bool ValidateCheckFramebufferStatus(ValidationContext *context, GLenum target)
+bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
 {
     if (!ValidFramebufferTarget(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
         return false;
     }
 
     return true;
 }
 
-bool ValidateClearColor(ValidationContext *context,
-                        GLfloat red,
-                        GLfloat green,
-                        GLfloat blue,
-                        GLfloat alpha)
+bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+    return true;
+}
+
+bool ValidateClearDepthf(Context *context, GLfloat depth)
 {
     return true;
 }
 
-bool ValidateClearDepthf(ValidationContext *context, GLfloat depth)
+bool ValidateClearStencil(Context *context, GLint s)
 {
     return true;
 }
 
-bool ValidateClearStencil(ValidationContext *context, GLint s)
-{
-    return true;
-}
-
-bool ValidateColorMask(ValidationContext *context,
+bool ValidateColorMask(Context *context,
                        GLboolean red,
                        GLboolean green,
                        GLboolean blue,
                        GLboolean alpha)
 {
     return true;
 }
 
-bool ValidateCompileShader(ValidationContext *context, GLuint shader)
+bool ValidateCompileShader(Context *context, GLuint shader)
 {
     return true;
 }
 
-bool ValidateCreateProgram(ValidationContext *context)
+bool ValidateCreateProgram(Context *context)
 {
     return true;
 }
 
-bool ValidateCullFace(ValidationContext *context, CullFaceMode mode)
+bool ValidateCullFace(Context *context, CullFaceMode mode)
 {
     switch (mode)
     {
         case CullFaceMode::Front:
         case CullFaceMode::Back:
         case CullFaceMode::FrontAndBack:
             break;
 
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
             return false;
     }
 
     return true;
 }
 
-bool ValidateDeleteProgram(ValidationContext *context, GLuint program)
+bool ValidateDeleteProgram(Context *context, GLuint program)
 {
     if (program == 0)
     {
         return false;
     }
 
     if (!context->getProgram(program))
     {
@@ -4909,17 +4910,17 @@ bool ValidateDeleteProgram(ValidationCon
             ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
             return false;
         }
     }
 
     return true;
 }
 
-bool ValidateDeleteShader(ValidationContext *context, GLuint shader)
+bool ValidateDeleteShader(Context *context, GLuint shader)
 {
     if (shader == 0)
     {
         return false;
     }
 
     if (!context->getShader(shader))
     {
@@ -4933,17 +4934,17 @@ bool ValidateDeleteShader(ValidationCont
             ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
             return false;
         }
     }
 
     return true;
 }
 
-bool ValidateDepthFunc(ValidationContext *context, GLenum func)
+bool ValidateDepthFunc(Context *context, GLenum func)
 {
     switch (func)
     {
         case GL_NEVER:
         case GL_ALWAYS:
         case GL_LESS:
         case GL_LEQUAL:
         case GL_EQUAL:
@@ -4955,121 +4956,93 @@ bool ValidateDepthFunc(ValidationContext
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
             return false;
     }
 
     return true;
 }
 
-bool ValidateDepthMask(ValidationContext *context, GLboolean flag)
+bool ValidateDepthMask(Context *context, GLboolean flag)
 {
     return true;
 }
 
-bool ValidateDetachShader(ValidationContext *context, GLuint program, GLuint shader)
+bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
 {
     Program *programObject = GetValidProgram(context, program);
     if (!programObject)
     {
         return false;
     }
 
     Shader *shaderObject = GetValidShader(context, shader);
     if (!shaderObject)
     {
         return false;
     }
 
-    const Shader *attachedShader = nullptr;
-
-    switch (shaderObject->getType())
-    {
-        case GL_VERTEX_SHADER:
-        {
-            attachedShader = programObject->getAttachedVertexShader();
-            break;
-        }
-        case GL_FRAGMENT_SHADER:
-        {
-            attachedShader = programObject->getAttachedFragmentShader();
-            break;
-        }
-        case GL_COMPUTE_SHADER:
-        {
-            attachedShader = programObject->getAttachedComputeShader();
-            break;
-        }
-        case GL_GEOMETRY_SHADER_EXT:
-        {
-            attachedShader = programObject->getAttachedGeometryShader();
-            break;
-        }
-        default:
-            UNREACHABLE();
-            return false;
-    }
-
+    const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
     if (attachedShader != shaderObject)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
         return false;
     }
 
     return true;
 }
 
-bool ValidateDisableVertexAttribArray(ValidationContext *context, GLuint index)
+bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
 {
     if (index >= MAX_VERTEX_ATTRIBS)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
         return false;
     }
 
     return true;
 }
 
-bool ValidateEnableVertexAttribArray(ValidationContext *context, GLuint index)
+bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
 {
     if (index >= MAX_VERTEX_ATTRIBS)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
         return false;
     }
 
     return true;
 }
 
-bool ValidateFinish(ValidationContext *context)
+bool ValidateFinish(Context *context)
 {
     return true;
 }
 
-bool ValidateFlush(ValidationContext *context)
+bool ValidateFlush(Context *context)
 {
     return true;
 }
 
-bool ValidateFrontFace(ValidationContext *context, GLenum mode)
+bool ValidateFrontFace(Context *context, GLenum mode)
 {
     switch (mode)
     {
         case GL_CW:
         case GL_CCW:
             break;
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
             return false;
     }
 
     return true;
 }
 
-bool ValidateGetActiveAttrib(ValidationContext *context,
+bool ValidateGetActiveAttrib(Context *context,
                              GLuint program,
                              GLuint index,
                              GLsizei bufsize,
                              GLsizei *length,
                              GLint *size,
                              GLenum *type,
                              GLchar *name)
 {
@@ -5090,17 +5063,17 @@ bool ValidateGetActiveAttrib(ValidationC
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
         return false;
     }
 
     return true;
 }
 
-bool ValidateGetActiveUniform(ValidationContext *context,
+bool ValidateGetActiveUniform(Context *context,
                               GLuint program,
                               GLuint index,
                               GLsizei bufsize,
                               GLsizei *length,
                               GLint *size,
                               GLenum *type,
                               GLchar *name)
 {
@@ -5121,17 +5094,17 @@ bool ValidateGetActiveUniform(Validation
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
         return false;
     }
 
     return true;
 }
 
-bool ValidateGetAttachedShaders(ValidationContext *context,
+bool ValidateGetAttachedShaders(Context *context,
                                 GLuint program,
                                 GLsizei maxcount,
                                 GLsizei *count,
                                 GLuint *shaders)
 {
     if (maxcount < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
@@ -5143,17 +5116,17 @@ bool ValidateGetAttachedShaders(Validati
     if (!programObject)
     {
         return false;
     }
 
     return true;
 }
 
-bool ValidateGetAttribLocation(ValidationContext *context, GLuint program, const GLchar *name)
+bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
 {
     // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
     // shader-related entry points
     if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
         return false;
     }
@@ -5170,43 +5143,43 @@ bool ValidateGetAttribLocation(Validatio
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
         return false;
     }
 
     return true;
 }
 
-bool ValidateGetBooleanv(ValidationContext *context, GLenum pname, GLboolean *params)
+bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
 {
     GLenum nativeType;
     unsigned int numParams = 0;
     return ValidateStateQuery(context, pname, &nativeType, &numParams);
 }
 
-bool ValidateGetError(ValidationContext *context)
+bool ValidateGetError(Context *context)
 {
     return true;
 }
 
-bool ValidateGetFloatv(ValidationContext *context, GLenum pname, GLfloat *params)
+bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
 {
     GLenum nativeType;
     unsigned int numParams = 0;
     return ValidateStateQuery(context, pname, &nativeType, &numParams);
 }
 
-bool ValidateGetIntegerv(ValidationContext *context, GLenum pname, GLint *params)
+bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
 {
     GLenum nativeType;
     unsigned int numParams = 0;
     return ValidateStateQuery(context, pname, &nativeType, &numParams);
 }
 
-bool ValidateGetProgramInfoLog(ValidationContext *context,
+bool ValidateGetProgramInfoLog(Context *context,
                                GLuint program,
                                GLsizei bufsize,
                                GLsizei *length,
                                GLchar *infolog)
 {
     if (bufsize < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
@@ -5217,17 +5190,17 @@ bool ValidateGetProgramInfoLog(Validatio
     if (!programObject)
     {
         return false;
     }
 
     return true;
 }
 
-bool ValidateGetShaderInfoLog(ValidationContext *context,
+bool ValidateGetShaderInfoLog(Context *context,
                               GLuint shader,
                               GLsizei bufsize,
                               GLsizei *length,
                               GLchar *infolog)
 {
     if (bufsize < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
@@ -5238,17 +5211,17 @@ bool ValidateGetShaderInfoLog(Validation
     if (!shaderObject)
     {
         return false;
     }
 
     return true;
 }
 
-bool ValidateGetShaderPrecisionFormat(ValidationContext *context,
+bool ValidateGetShaderPrecisionFormat(Context *context,
                                       GLenum shadertype,
                                       GLenum precisiontype,
                                       GLint *range,
                                       GLint *precision)
 {
     switch (shadertype)
     {
         case GL_VERTEX_SHADER:
@@ -5276,17 +5249,17 @@ bool ValidateGetShaderPrecisionFormat(Va
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
             return false;
     }
 
     return true;
 }
 
-bool ValidateGetShaderSource(ValidationContext *context,
+bool ValidateGetShaderSource(Context *context,
                              GLuint shader,
                              GLsizei bufsize,
                              GLsizei *length,
                              GLchar *source)
 {
     if (bufsize < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
@@ -5297,17 +5270,17 @@ bool ValidateGetShaderSource(ValidationC
     if (!shaderObject)
     {
         return false;
     }
 
     return true;
 }
 
-bool ValidateGetUniformLocation(ValidationContext *context, GLuint program, const GLchar *name)
+bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
 {
     if (strstr(name, "gl_") == name)
     {
         return false;
     }
 
     // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
     // shader-related entry points
@@ -5328,17 +5301,17 @@ bool ValidateGetUniformLocation(Validati
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
         return false;
     }
 
     return true;
 }
 
-bool ValidateHint(ValidationContext *context, GLenum target, GLenum mode)
+bool ValidateHint(Context *context, GLenum target, GLenum mode)
 {
     switch (mode)
     {
         case GL_FASTEST:
         case GL_NICEST:
         case GL_DONT_CARE:
             break;
 
@@ -5364,47 +5337,47 @@ bool ValidateHint(ValidationContext *con
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
             return false;
     }
 
     return true;
 }
 
-bool ValidateIsBuffer(ValidationContext *context, GLuint buffer)
+bool ValidateIsBuffer(Context *context, GLuint buffer)
 {
     return true;
 }
 
-bool ValidateIsFramebuffer(ValidationContext *context, GLuint framebuffer)
+bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
 {
     return true;
 }
 
-bool ValidateIsProgram(ValidationContext *context, GLuint program)
+bool ValidateIsProgram(Context *context, GLuint program)
 {
     return true;
 }
 
-bool ValidateIsRenderbuffer(ValidationContext *context, GLuint renderbuffer)
+bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
 {
     return true;
 }
 
-bool ValidateIsShader(ValidationContext *context, GLuint shader)
+bool ValidateIsShader(Context *context, GLuint shader)
 {
     return true;
 }
 
-bool ValidateIsTexture(ValidationContext *context, GLuint texture)
+bool ValidateIsTexture(Context *context, GLuint texture)
 {
     return true;
 }
 
-bool ValidatePixelStorei(ValidationContext *context, GLenum pname, GLint param)
+bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
 {
     if (context->getClientMajorVersion() < 3)
     {
         switch (pname)
         {
             case GL_UNPACK_IMAGE_HEIGHT:
             case GL_UNPACK_SKIP_IMAGES:
                 context->handleError(InvalidEnum());
@@ -5476,43 +5449,43 @@ bool ValidatePixelStorei(ValidationConte
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
             return false;
     }
 
     return true;
 }
 
-bool ValidatePolygonOffset(ValidationContext *context, GLfloat factor, GLfloat units)
+bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
 {
     return true;
 }
 
-bool ValidateReleaseShaderCompiler(ValidationContext *context)
+bool ValidateReleaseShaderCompiler(Context *context)
 {
     return true;
 }
 
-bool ValidateSampleCoverage(ValidationContext *context, GLfloat value, GLboolean invert)
+bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
 {
     return true;
 }
 
-bool ValidateScissor(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
+bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
 {
     if (width < 0 || height < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
         return false;
     }
 
     return true;
 }
 
-bool ValidateShaderBinary(ValidationContext *context,
+bool ValidateShaderBinary(Context *context,
                           GLsizei n,
                           const GLuint *shaders,
                           GLenum binaryformat,
                           const void *binary,
                           GLsizei length)
 {
     const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
     if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
@@ -5520,17 +5493,17 @@ bool ValidateShaderBinary(ValidationCont
     {
         context->handleError(InvalidEnum() << "Invalid shader binary format.");
         return false;
     }
 
     return true;
 }
 
-bool ValidateShaderSource(ValidationContext *context,
+bool ValidateShaderSource(Context *context,
                           GLuint shader,
                           GLsizei count,
                           const GLchar *const *string,
                           const GLint *length)
 {
     if (count < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
@@ -5560,65 +5533,61 @@ bool ValidateShaderSource(ValidationCont
     if (!shaderObject)
     {
         return false;
     }
 
     return true;
 }
 
-bool ValidateStencilFunc(ValidationContext *context, GLenum func, GLint ref, GLuint mask)
+bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
 {
     if (!IsValidStencilFunc(func))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
         return false;
     }
 
     return true;
 }
 
-bool ValidateStencilFuncSeparate(ValidationContext *context,
-                                 GLenum face,
-                                 GLenum func,
-                                 GLint ref,
-                                 GLuint mask)
+bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
 {
     if (!IsValidStencilFace(face))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
         return false;
     }
 
     if (!IsValidStencilFunc(func))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
         return false;
     }
 
     return true;
 }
 
-bool ValidateStencilMask(ValidationContext *context, GLuint mask)
+bool ValidateStencilMask(Context *context, GLuint mask)
 {
     return true;
 }
 
-bool ValidateStencilMaskSeparate(ValidationContext *context, GLenum face, GLuint mask)
+bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
 {
     if (!IsValidStencilFace(face))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
         return false;
     }
 
     return true;
 }
 
-bool ValidateStencilOp(ValidationContext *context, GLenum fail, GLenum zfail, GLenum zpass)
+bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
 {
     if (!IsValidStencilOp(fail))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
         return false;
     }
 
     if (!IsValidStencilOp(zfail))
@@ -5631,221 +5600,207 @@ bool ValidateStencilOp(ValidationContext
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
         return false;
     }
 
     return true;
 }
 
-bool ValidateStencilOpSeparate(ValidationContext *context,
+bool ValidateStencilOpSeparate(Context *context,
                                GLenum face,
                                GLenum fail,
                                GLenum zfail,
                                GLenum zpass)
 {
     if (!IsValidStencilFace(face))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
         return false;
     }
 
     return ValidateStencilOp(context, fail, zfail, zpass);
 }
 
-bool ValidateUniform1f(ValidationContext *context, GLint location, GLfloat x)
+bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
 {
     return ValidateUniform(context, GL_FLOAT, location, 1);
 }
 
-bool ValidateUniform1fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
+bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
 {
     return ValidateUniform(context, GL_FLOAT, location, count);
 }
 
-bool ValidateUniform1i(ValidationContext *context, GLint location, GLint x)
+bool ValidateUniform1i(Context *context, GLint location, GLint x)
 {
     return ValidateUniform1iv(context, location, 1, &x);
 }
 
-bool ValidateUniform2f(ValidationContext *context, GLint location, GLfloat x, GLfloat y)
+bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
 {
     return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
 }
 
-bool ValidateUniform2fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
+bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
 {
     return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
 }
 
-bool ValidateUniform2i(ValidationContext *context, GLint location, GLint x, GLint y)
+bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
 {
     return ValidateUniform(context, GL_INT_VEC2, location, 1);
 }
 
-bool ValidateUniform2iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
+bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
 {
     return ValidateUniform(context, GL_INT_VEC2, location, count);
 }
 
-bool ValidateUniform3f(ValidationContext *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
+bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
 {
     return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
 }
 
-bool ValidateUniform3fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
+bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
 {
     return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
 }
 
-bool ValidateUniform3i(ValidationContext *context, GLint location, GLint x, GLint y, GLint z)
+bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
 {
     return ValidateUniform(context, GL_INT_VEC3, location, 1);
 }
 
-bool ValidateUniform3iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
+bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
 {
     return ValidateUniform(context, GL_INT_VEC3, location, count);
 }
 
-bool ValidateUniform4f(ValidationContext *context,
-                       GLint location,
-                       GLfloat x,
-                       GLfloat y,
-                       GLfloat z,
-                       GLfloat w)
+bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
 {
     return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
 }
 
-bool ValidateUniform4fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
+bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
 {
     return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
 }
 
-bool ValidateUniform4i(ValidationContext *context,
-                       GLint location,
-                       GLint x,
-                       GLint y,
-                       GLint z,
-                       GLint w)
+bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
 {
     return ValidateUniform(context, GL_INT_VEC4, location, 1);
 }
 
-bool ValidateUniform4iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
+bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
 {
     return ValidateUniform(context, GL_INT_VEC4, location, count);
 }
 
-bool ValidateUniformMatrix2fv(ValidationContext *context,
+bool ValidateUniformMatrix2fv(Context *context,
                               GLint location,
                               GLsizei count,
                               GLboolean transpose,
                               const GLfloat *value)
 {
     return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
 }
 
-bool ValidateUniformMatrix3fv(ValidationContext *context,
+bool ValidateUniformMatrix3fv(Context *context,
                               GLint location,
                               GLsizei count,
                               GLboolean transpose,
                               const GLfloat *value)
 {
     return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
 }
 
-bool ValidateUniformMatrix4fv(ValidationContext *context,
+bool ValidateUniformMatrix4fv(Context *context,
                               GLint location,
                               GLsizei count,
                               GLboolean transpose,
                               const GLfloat *value)
 {
     return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
 }
 
-bool ValidateValidateProgram(ValidationContext *context, GLuint program)
+bool ValidateValidateProgram(Context *context, GLuint program)
 {
     Program *programObject = GetValidProgram(context, program);
 
     if (!programObject)
     {
         return false;
     }
 
     return true;
 }
 
-bool ValidateVertexAttrib1f(ValidationContext *context, GLuint index, GLfloat x)
-{
-    return ValidateVertexAttribIndex(context, index);
-}
-
-bool ValidateVertexAttrib1fv(ValidationContext *context, GLuint index, const GLfloat *values)
+bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
 {
     return ValidateVertexAttribIndex(context, index);
 }
 
-bool ValidateVertexAttrib2f(ValidationContext *context, GLuint index, GLfloat x, GLfloat y)
+bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
 {
     return ValidateVertexAttribIndex(context, index);
 }
 
-bool ValidateVertexAttrib2fv(ValidationContext *context, GLuint index, const GLfloat *values)
+bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
 {
     return ValidateVertexAttribIndex(context, index);
 }
 
-bool ValidateVertexAttrib3f(ValidationContext *context,
-                            GLuint index,
-                            GLfloat x,
-                            GLfloat y,
-                            GLfloat z)
+bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
+{
+    return ValidateVertexAttribIndex(context, index);
+}
+
+bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
 {
     return ValidateVertexAttribIndex(context, index);
 }
 
-bool ValidateVertexAttrib3fv(ValidationContext *context, GLuint index, const GLfloat *values)
+bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
 {
     return ValidateVertexAttribIndex(context, index);
 }
 
-bool ValidateVertexAttrib4f(ValidationContext *context,
+bool ValidateVertexAttrib4f(Context *context,
                             GLuint index,
                             GLfloat x,
                             GLfloat y,
                             GLfloat z,
                             GLfloat w)
 {
     return ValidateVertexAttribIndex(context, index);
 }
 
-bool ValidateVertexAttrib4fv(ValidationContext *context, GLuint index, const GLfloat *values)
+bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
 {
     return ValidateVertexAttribIndex(context, index);
 }
 
-bool ValidateViewport(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
+bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
 {
     if (width < 0 || height < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
         return false;
     }
 
     return true;
 }
 
-bool ValidateDrawArrays(ValidationContext *context, GLenum mode, GLint first, GLsizei count)
+bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count)
 {
     return ValidateDrawArraysCommon(context, mode, first, count, 1);
 }
 
-bool ValidateDrawElements(ValidationContext *context,
+bool ValidateDrawElements(Context *context,
                           GLenum mode,
                           GLsizei count,
                           GLenum type,
                           const void *indices)
 {
     return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
 }
 
@@ -5854,23 +5809,23 @@ bool ValidateGetFramebufferAttachmentPar
                                                  GLenum attachment,
                                                  GLenum pname,
                                                  GLint *params)
 {
     return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
                                                            nullptr);
 }
 
-bool ValidateGetProgramiv(ValidationContext *context, GLuint program, GLenum pname, GLint *params)
+bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
 {
     return ValidateGetProgramivBase(context, program, pname, nullptr);
 }
 
-bool ValidateCopyTexImage2D(ValidationContext *context,
-                            GLenum target,
+bool ValidateCopyTexImage2D(Context *context,
+                            TextureTarget target,
                             GLint level,
                             GLenum internalformat,
                             GLint x,
                             GLint y,
                             GLsizei width,
                             GLsizei height,
                             GLint border)
 {
@@ -5881,17 +5836,17 @@ bool ValidateCopyTexImage2D(ValidationCo
     }
 
     ASSERT(context->getClientMajorVersion() == 3);
     return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
                                                0, x, y, width, height, border);
 }
 
 bool ValidateCopyTexSubImage2D(Context *context,
-                               GLenum target,
+                               TextureTarget target,
                                GLint level,
                                GLint xoffset,
                                GLint yoffset,
                                GLint x,
                                GLint y,
                                GLsizei width,
                                GLsizei height)
 {
@@ -5979,17 +5934,17 @@ bool ValidateFramebufferRenderbuffer(Con
 
     return ValidateFramebufferRenderbufferParameters(context, target, attachment,
                                                      renderbuffertarget, renderbuffer);
 }
 
 bool ValidateFramebufferTexture2D(Context *context,
                                   GLenum target,
                                   GLenum attachment,
-                                  GLenum textarget,
+                                  TextureTarget textarget,
                                   GLuint texture,
                                   GLint level)
 {
     // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
     // extension
     if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
         level != 0)
     {
@@ -6006,82 +5961,82 @@ bool ValidateFramebufferTexture2D(Contex
     {
         gl::Texture *tex = context->getTexture(texture);
         ASSERT(tex);
 
         const gl::Caps &caps = context->getCaps();
 
         switch (textarget)
         {
-            case GL_TEXTURE_2D:
+            case TextureTarget::_2D:
             {
                 if (level > gl::log2(caps.max2DTextureSize))
                 {
                     context->handleError(InvalidValue());
                     return false;
                 }
-                if (tex->getTarget() != GL_TEXTURE_2D)
+                if (tex->getType() != TextureType::_2D)
                 {
                     ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
                     return false;
                 }
             }
             break;
 
-            case GL_TEXTURE_RECTANGLE_ANGLE:
+            case TextureTarget::Rectangle:
             {
                 if (level != 0)
                 {
                     context->handleError(InvalidValue());
                     return false;
                 }
-                if (tex->getTarget() != GL_TEXTURE_RECTANGLE_ANGLE)
+                if (tex->getType() != TextureType::Rectangle)
                 {
                     context->handleError(InvalidOperation()
                                          << "Textarget must match the texture target type.");
                     return false;
                 }
             }
             break;
 
-            case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-            case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-            case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-            case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-            case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-            case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+            case TextureTarget::CubeMapNegativeX:
+            case TextureTarget::CubeMapNegativeY:
+            case TextureTarget::CubeMapNegativeZ:
+            case TextureTarget::CubeMapPositiveX:
+            case TextureTarget::CubeMapPositiveY:
+            case TextureTarget::CubeMapPositiveZ:
             {
                 if (level > gl::log2(caps.maxCubeMapTextureSize))
                 {
                     context->handleError(InvalidValue());
                     return false;
                 }
-                if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
+                if (tex->getType() != TextureType::CubeMap)
                 {
                     context->handleError(InvalidOperation()
                                          << "Textarget must match the texture target type.");
                     return false;
                 }
             }
             break;
 
-            case GL_TEXTURE_2D_MULTISAMPLE:
+            case TextureTarget::_2DMultisample:
             {
                 if (context->getClientVersion() < ES_3_1)
                 {
                     ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
                     return false;
                 }
 
                 if (level != 0)
                 {
                     ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
                     return false;
                 }
-                if (tex->getTarget() != GL_TEXTURE_2D_MULTISAMPLE)
+                if (tex->getType() != TextureType::_2DMultisample)
                 {
                     context->handleError(InvalidOperation()
                                          << "Textarget must match the texture target type.");
                     return false;
                 }
             }
             break;
 
@@ -6116,17 +6071,17 @@ bool ValidateGenRenderbuffers(Context *c
     return ValidateGenOrDelete(context, n);
 }
 
 bool ValidateGenTextures(Context *context, GLint n, GLuint *)
 {
     return ValidateGenOrDelete(context, n);
 }
 
-bool ValidateGenerateMipmap(Context *context, GLenum target)
+bool ValidateGenerateMipmap(Context *context, TextureType target)
 {
     if (!ValidTextureTarget(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
         return false;
     }
 
     Texture *texture = context->getTargetTexture(target);
@@ -6142,17 +6097,19 @@ bool ValidateGenerateMipmap(Context *con
     // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
     // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
     if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
     {
         context->handleError(InvalidOperation());
         return false;
     }
 
-    GLenum baseTarget  = (target == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : target;
+    TextureTarget baseTarget = (target == TextureType::CubeMap)
+                                   ? TextureTarget::CubeMapPositiveX
+                                   : NonCubeTextureTypeToTarget(target);
     const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
     if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
         format.stencilBits > 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
         return false;
     }
 
@@ -6185,33 +6142,33 @@ bool ValidateGenerateMipmap(Context *con
         return false;
     }
 
     // Non-power of 2 ES2 check
     if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
         (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
          !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
     {
-        ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ANGLE ||
-               target == GL_TEXTURE_CUBE_MAP);
+        ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
+               target == TextureType::CubeMap);
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
         return false;
     }
 
     // Cube completeness check
-    if (target == GL_TEXTURE_CUBE_MAP && !texture->getTextureState().isCubeComplete())
+    if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
         return false;
     }
 
     return true;
 }
 
-bool ValidateGetBufferParameteriv(ValidationContext *context,
+bool ValidateGetBufferParameteriv(Context *context,
                                   BufferBinding target,
                                   GLenum pname,
                                   GLint *params)
 {
     return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
 }
 
 bool ValidateGetRenderbufferParameteriv(Context *context,
@@ -6222,22 +6179,22 @@ bool ValidateGetRenderbufferParameteriv(
     return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
 }
 
 bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
 {
     return ValidateGetShaderivBase(context, shader, pname, nullptr);
 }
 
-bool ValidateGetTexParameterfv(Context *context, GLenum target, GLenum pname, GLfloat *params)
+bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
 {
     return ValidateGetTexParameterBase(context, target, pname, nullptr);
 }
 
-bool ValidateGetTexParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
+bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
 {
     return ValidateGetTexParameterBase(context, target, pname, nullptr);
 }
 
 bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
 {
     return ValidateGetUniformBase(context, program, location);
 }
@@ -6301,32 +6258,35 @@ bool ValidateReadPixels(Context *context
                         GLenum format,
                         GLenum type,
                         void *pixels)
 {
     return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
                                   nullptr, pixels);
 }
 
-bool ValidateTexParameterf(Context *context, GLenum target, GLenum pname, GLfloat param)
+bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
 {
     return ValidateTexParameterBase(context, target, pname, -1, &param);
 }
 
-bool ValidateTexParameterfv(Context *context, GLenum target, GLenum pname, const GLfloat *params)
+bool ValidateTexParameterfv(Context *context,
+                            TextureType target,
+                            GLenum pname,
+                            const GLfloat *params)
 {
     return ValidateTexParameterBase(context, target, pname, -1, params);
 }
 
-bool ValidateTexParameteri(Context *context, GLenum target, GLenum pname, GLint param)
+bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
 {
     return ValidateTexParameterBase(context, target, pname, -1, &param);
 }
 
-bool ValidateTexParameteriv(Context *context, GLenum target, GLenum pname, const GLint *params)
+bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
 {
     return ValidateTexParameterBase(context, target, pname, -1, params);
 }
 
 bool ValidateUseProgram(Context *context, GLuint program)
 {
     if (program != 0)
     {
@@ -6555,36 +6515,36 @@ bool ValidateTestFenceNV(Context *contex
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
         return false;
     }
 
     return true;
 }
 
 bool ValidateTexStorage2DEXT(Context *context,
-                             GLenum target,
+                             TextureType type,
                              GLsizei levels,
                              GLenum internalformat,
                              GLsizei width,
                              GLsizei height)
 {
     if (!context->getExtensions().textureStorage)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
         return false;
     }
 
     if (context->getClientMajorVersion() < 3)
     {
-        return ValidateES2TexStorageParameters(context, target, levels, internalformat, width,
+        return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
                                                height);
     }
 
     ASSERT(context->getClientMajorVersion() >= 3);
-    return ValidateES3TexStorage2DParameters(context, target, levels, internalformat, width, height,
+    return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
                                              1);
 }
 
 bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
 {
     if (!context->getExtensions().instancedArrays)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
@@ -6654,17 +6614,17 @@ bool ValidateTexStorage1DEXT(Context *co
                              GLsizei width)
 {
     UNIMPLEMENTED();
     ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
     return false;
 }
 
 bool ValidateTexStorage3DEXT(Context *context,
-                             GLenum target,
+                             TextureType target,
                              GLsizei levels,
                              GLenum internalformat,
                              GLsizei width,
                              GLsizei height,
                              GLsizei depth)
 {
     if (!context->getExtensions().textureStorage)
     {
--- a/gfx/angle/checkout/src/libANGLE/validationES2.h
+++ b/gfx/angle/checkout/src/libANGLE/validationES2.h
@@ -12,31 +12,30 @@
 #include "libANGLE/PackedGLEnums.h"
 
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
 namespace gl
 {
 class Context;
-class ValidationContext;
 
 bool ValidateES2TexStorageParameters(Context *context,
                                      GLenum target,
                                      GLsizei levels,
                                      GLenum internalformat,
                                      GLsizei width,
                                      GLsizei height);
 
 bool ValidateDiscardFramebufferEXT(Context *context,
                                    GLenum target,
                                    GLsizei numAttachments,
                                    const GLenum *attachments);
 
-bool ValidateDrawBuffersEXT(ValidationContext *context, GLsizei n, const GLenum *bufs);
+bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs);
 
 bool ValidateBindVertexArrayOES(Context *context, GLuint array);
 bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays);
 bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays);
 bool ValidateIsVertexArrayOES(Context *context, GLuint array);
 
 bool ValidateProgramBinaryOES(Context *context,
                               GLuint program,
@@ -99,113 +98,118 @@ bool ValidateObjectPtrLabelKHR(Context *
                                GLsizei length,
                                const GLchar *label);
 bool ValidateGetObjectPtrLabelKHR(Context *context,
                                   const void *ptr,
                                   GLsizei bufSize,
                                   GLsizei *length,
                                   GLchar *label);
 bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params);
+bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
+                                               GLenum pname,
+                                               GLsizei bufSize,
+                                               GLsizei *length,
+                                               void **params);
 bool ValidateBlitFramebufferANGLE(Context *context,
                                   GLint srcX0,
                                   GLint srcY0,
                                   GLint srcX1,
                                   GLint srcY1,
                                   GLint dstX0,
                                   GLint dstY0,
                                   GLint dstX1,
                                   GLint dstY1,
                                   GLbitfield mask,
                                   GLenum filter);
 
-bool ValidateClear(ValidationContext *context, GLbitfield mask);
+bool ValidateClear(Context *context, GLbitfield mask);
 bool ValidateTexImage2D(Context *context,
-                        GLenum target,
+                        TextureTarget target,
                         GLint level,
                         GLint internalformat,
                         GLsizei width,
                         GLsizei height,
                         GLint border,
                         GLenum format,
                         GLenum type,
                         const void *pixels);
 bool ValidateTexImage2DRobust(Context *context,
-                              GLenum target,
+                              TextureTarget target,
                               GLint level,
                               GLint internalformat,
                               GLsizei width,
                               GLsizei height,
                               GLint border,
                               GLenum format,
                               GLenum type,
                               GLsizei bufSize,
                               const void *pixels);
 bool ValidateTexSubImage2D(Context *context,
-                           GLenum target,
+                           TextureTarget target,
                            GLint level,
                            GLint xoffset,
                            GLint yoffset,
                            GLsizei width,
                            GLsizei height,
                            GLenum format,
                            GLenum type,
                            const void *pixels);
 bool ValidateTexSubImage2DRobustANGLE(Context *context,
-                                      GLenum target,
+                                      TextureTarget target,
                                       GLint level,
                                       GLint xoffset,
                                       GLint yoffset,
                                       GLsizei width,
                                       GLsizei height,
                                       GLenum format,
                                       GLenum type,
                                       GLsizei bufSize,
                                       const void *pixels);
 bool ValidateCompressedTexImage2D(Context *context,
-                                  GLenum target,
+                                  TextureTarget target,
                                   GLint level,
                                   GLenum internalformat,
                                   GLsizei width,
                                   GLsizei height,
                                   GLint border,
                                   GLsizei imageSize,
                                   const void *data);
 bool ValidateCompressedTexSubImage2D(Context *context,
-                                     GLenum target,
+                                     TextureTarget target,
                                      GLint level,
                                      GLint xoffset,
                                      GLint yoffset,
                                      GLsizei width,
                                      GLsizei height,
                                      GLenum format,
                                      GLsizei imageSize,
                                      const void *data);
 bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
-                                             GLenum target,
+                                             TextureTarget target,
                                              GLint level,
                                              GLenum internalformat,
                                              GLsizei width,
                                              GLsizei height,
                                              GLint border,
                                              GLsizei imageSize,
                                              GLsizei dataSize,
                                              const void *data);
 bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
-                                                GLenum target,
+                                                TextureTarget target,
                                                 GLint level,
                                                 GLint xoffset,
                                                 GLint yoffset,
                                                 GLsizei width,
                                                 GLsizei height,
                                                 GLenum format,
                                                 GLsizei imageSize,
                                                 GLsizei dataSize,
                                                 const void *data);
 
-bool ValidateBindTexture(Context *context, GLenum target, GLuint texture);
+bool ValidateBindTexture(Context *context, TextureType target, GLuint texture);
 
 bool ValidateGetBufferPointervOES(Context *context,
                                   BufferBinding target,
                                   GLenum pname,
                                   void **params);
 bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access);
 bool ValidateUnmapBufferOES(Context *context, BufferBinding target);
 bool ValidateMapBufferRangeEXT(Context *context,
@@ -243,28 +247,30 @@ bool ValidatePathParameteriCHROMIUM(Cont
 bool ValidateGetPathParameterfvCHROMIUM(Context *context,
                                         GLuint path,
                                         GLenum pname,
                                         GLfloat *value);
 bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value);
 bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask);
 bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask);
 bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask);
+bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode);
+bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode);
 bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode);
 bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
                                               GLuint path,
                                               GLenum fillMode,
                                               GLuint mask,
                                               GLenum coverMode);
 bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
                                                 GLuint path,
                                                 GLint reference,
                                                 GLuint mask,
                                                 GLenum coverMode);
-bool ValidateIsPathCHROMIUM(Context *context);
+bool ValidateIsPathCHROMIUM(Context *context, GLuint path);
 bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
                                             GLsizei numPaths,
                                             GLenum pathNameType,
                                             const void *paths,
                                             GLuint pathBase,
                                             GLenum coverMode,
                                             GLenum transformType,
                                             const GLfloat *transformValues);
@@ -323,309 +329,285 @@ bool ValidateProgramPathFragmentInputGen
                                                  GLint location,
                                                  GLenum genMode,
                                                  GLint components,
                                                  const GLfloat *coeffs);
 
 bool ValidateCopyTextureCHROMIUM(Context *context,
                                  GLuint sourceId,
                                  GLint sourceLevel,
-                                 GLenum destTarget,
+                                 TextureTarget destTarget,
                                  GLuint destId,
                                  GLint destLevel,
                                  GLint internalFormat,
                                  GLenum destType,
                                  GLboolean unpackFlipY,
                                  GLboolean unpackPremultiplyAlpha,
                                  GLboolean unpackUnmultiplyAlpha);
 bool ValidateCopySubTextureCHROMIUM(Context *context,
                                     GLuint sourceId,
                                     GLint sourceLevel,
-                                    GLenum destTarget,
+                                    TextureTarget destTarget,
                                     GLuint destId,
                                     GLint destLevel,
                                     GLint xoffset,
                                     GLint yoffset,
                                     GLint x,
                                     GLint y,
                                     GLsizei width,
                                     GLsizei height,
                                     GLboolean unpackFlipY,
                                     GLboolean unpackPremultiplyAlpha,
                                     GLboolean unpackUnmultiplyAlpha);
 bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId);
 
-bool ValidateCreateShader(Context *context, GLenum type);
-bool ValidateBufferData(ValidationContext *context,
+bool ValidateCreateShader(Context *context, ShaderType type);
+bool ValidateBufferData(Context *context,
                         BufferBinding target,
                         GLsizeiptr size,
                         const void *data,
                         BufferUsage usage);
-bool ValidateBufferSubData(ValidationContext *context,
+bool ValidateBufferSubData(Context *context,
                            BufferBinding target,
                            GLintptr offset,
                            GLsizeiptr size,
                            const void *data);
 
 bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name);
 
-bool ValidateActiveTexture(ValidationContext *context, GLenum texture);
-bool ValidateAttachShader(ValidationContext *context, GLuint program, GLuint shader);
-bool ValidateBindAttribLocation(ValidationContext *context,
-                                GLuint program,
-                                GLuint index,
-                                const GLchar *name);
-bool ValidateBindBuffer(ValidationContext *context, BufferBinding target, GLuint buffer);
-bool ValidateBindFramebuffer(ValidationContext *context, GLenum target, GLuint framebuffer);
-bool ValidateBindRenderbuffer(ValidationContext *context, GLenum target, GLuint renderbuffer);
-bool ValidateBlendColor(ValidationContext *context,
+bool ValidateActiveTexture(Context *context, GLenum texture);
+bool ValidateAttachShader(Context *context, GLuint program, GLuint shader);
+bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name);
+bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer);
+bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer);
+bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer);
+bool ValidateBlendColor(Context *context,
                         GLclampf red,
                         GLclampf green,
                         GLclampf blue,
                         GLclampf alpha);
-bool ValidateBlendEquation(ValidationContext *context, GLenum mode);
-bool ValidateBlendEquationSeparate(ValidationContext *context, GLenum modeRGB, GLenum modeAlpha);
-bool ValidateBlendFunc(ValidationContext *context, GLenum sfactor, GLenum dfactor);
-bool ValidateBlendFuncSeparate(ValidationContext *context,
+bool ValidateBlendEquation(Context *context, GLenum mode);
+bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha);
+bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor);
+bool ValidateBlendFuncSeparate(Context *context,
                                GLenum srcRGB,
                                GLenum dstRGB,
                                GLenum srcAlpha,
                                GLenum dstAlpha);
 
 bool ValidateGetString(Context *context, GLenum name);
-bool ValidateLineWidth(ValidationContext *context, GLfloat width);
-bool ValidateVertexAttribPointer(ValidationContext *context,
+bool ValidateLineWidth(Context *context, GLfloat width);
+bool ValidateVertexAttribPointer(Context *context,
                                  GLuint index,
                                  GLint size,
                                  GLenum type,
                                  GLboolean normalized,
                                  GLsizei stride,
                                  const void *ptr);
 
-bool ValidateDepthRangef(ValidationContext *context, GLclampf zNear, GLclampf zFar);
-bool ValidateRenderbufferStorage(ValidationContext *context,
+bool ValidateDepthRangef(Context *context, GLclampf zNear, GLclampf zFar);
+bool ValidateRenderbufferStorage(Context *context,
                                  GLenum target,
                                  GLenum internalformat,
                                  GLsizei width,
                                  GLsizei height);
-bool ValidateRenderbufferStorageMultisampleANGLE(ValidationContext *context,
+bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
                                                  GLenum target,
                                                  GLsizei samples,
                                                  GLenum internalformat,
                                                  GLsizei width,
                                                  GLsizei height);
 
-bool ValidateCheckFramebufferStatus(ValidationContext *context, GLenum target);
-bool ValidateClearColor(ValidationContext *context,
+bool ValidateCheckFramebufferStatus(Context *context, GLenum target);
+bool ValidateClearColor(Context *context,
                         GLclampf red,
                         GLclampf green,
                         GLclampf blue,
                         GLclampf alpha);
-bool ValidateClearDepthf(ValidationContext *context, GLclampf depth);
-bool ValidateClearStencil(ValidationContext *context, GLint s);
-bool ValidateColorMask(ValidationContext *context,
+bool ValidateClearDepthf(Context *context, GLclampf depth);
+bool ValidateClearStencil(Context *context, GLint s);
+bool ValidateColorMask(Context *context,
                        GLboolean red,
                        GLboolean green,
                        GLboolean blue,
                        GLboolean alpha);
-bool ValidateCompileShader(ValidationContext *context, GLuint shader);
-bool ValidateCreateProgram(ValidationContext *context);
-bool ValidateCullFace(ValidationContext *context, CullFaceMode mode);
-bool ValidateDeleteProgram(ValidationContext *context, GLuint program);
-bool ValidateDeleteShader(ValidationContext *context, GLuint shader);
-bool ValidateDepthFunc(ValidationContext *context, GLenum func);
-bool ValidateDepthMask(ValidationContext *context, GLboolean flag);
-bool ValidateDetachShader(ValidationContext *context, GLuint program, GLuint shader);
-bool ValidateDisableVertexAttribArray(ValidationContext *context, GLuint index);
-bool ValidateEnableVertexAttribArray(ValidationContext *context, GLuint index);
-bool ValidateFinish(ValidationContext *context);
-bool ValidateFlush(ValidationContext *context);
-bool ValidateFrontFace(ValidationContext *context, GLenum mode);
-bool ValidateGetActiveAttrib(ValidationContext *context,
+bool ValidateCompileShader(Context *context, GLuint shader);
+bool ValidateCreateProgram(Context *context);
+bool ValidateCullFace(Context *context, CullFaceMode mode);
+bool ValidateDeleteProgram(Context *context, GLuint program);
+bool ValidateDeleteShader(Context *context, GLuint shader);
+bool ValidateDepthFunc(Context *context, GLenum func);
+bool ValidateDepthMask(Context *context, GLboolean flag);
+bool ValidateDetachShader(Context *context, GLuint program, GLuint shader);
+bool ValidateDisableVertexAttribArray(Context *context, GLuint index);
+bool ValidateEnableVertexAttribArray(Context *context, GLuint index);
+bool ValidateFinish(Context *context);
+bool ValidateFlush(Context *context);
+bool ValidateFrontFace(Context *context, GLenum mode);
+bool ValidateGetActiveAttrib(Context *context,
                              GLuint program,
                              GLuint index,
                              GLsizei bufsize,
                              GLsizei *length,
                              GLint *size,
                              GLenum *type,
                              GLchar *name);
-bool ValidateGetActiveUniform(ValidationContext *context,
+bool ValidateGetActiveUniform(Context *context,
                               GLuint program,
                               GLuint index,
                               GLsizei bufsize,
                               GLsizei *length,
                               GLint *size,
                               GLenum *type,
                               GLchar *name);
-bool ValidateGetAttachedShaders(ValidationContext *context,
+bool ValidateGetAttachedShaders(Context *context,
                                 GLuint program,
                                 GLsizei maxcount,
                                 GLsizei *count,
                                 GLuint *shaders);
-bool ValidateGetAttribLocation(ValidationContext *context, GLuint program, const GLchar *name);
-bool ValidateGetBooleanv(ValidationContext *context, GLenum pname, GLboolean *params);
-bool ValidateGetError(ValidationContext *context);
-bool ValidateGetFloatv(ValidationContext *context, GLenum pname, GLfloat *params);
-bool ValidateGetIntegerv(ValidationContext *context, GLenum pname, GLint *params);
-bool ValidateGetProgramInfoLog(ValidationContext *context,
+bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name);
+bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params);
+bool ValidateGetError(Context *context);
+bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params);
+bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params);
+bool ValidateGetProgramInfoLog(Context *context,
                                GLuint program,
                                GLsizei bufsize,
                                GLsizei *length,
                                GLchar *infolog);
-bool ValidateGetShaderInfoLog(ValidationContext *context,
+bool ValidateGetShaderInfoLog(Context *context,
                               GLuint shader,
                               GLsizei bufsize,
                               GLsizei *length,
                               GLchar *infolog);
-bool ValidateGetShaderPrecisionFormat(ValidationContext *context,
+bool ValidateGetShaderPrecisionFormat(Context *context,
                                       GLenum shadertype,
                                       GLenum precisiontype,
                                       GLint *range,
                                       GLint *precision);
-bool ValidateGetShaderSource(ValidationContext *context,
+bool ValidateGetShaderSource(Context *context,
                              GLuint shader,
                              GLsizei bufsize,
                              GLsizei *length,
                              GLchar *source);
-bool ValidateGetUniformLocation(ValidationContext *context, GLuint program, const GLchar *name);
-bool ValidateHint(ValidationContext *context, GLenum target, GLenum mode);
-bool ValidateIsBuffer(ValidationContext *context, GLuint buffer);
-bool ValidateIsFramebuffer(ValidationContext *context, GLuint framebuffer);
-bool ValidateIsProgram(ValidationContext *context, GLuint program);
-bool ValidateIsRenderbuffer(ValidationContext *context, GLuint renderbuffer);
-bool ValidateIsShader(ValidationContext *context, GLuint shader);
-bool ValidateIsTexture(ValidationContext *context, GLuint texture);
-bool ValidatePixelStorei(ValidationContext *context, GLenum pname, GLint param);
-bool ValidatePolygonOffset(ValidationContext *context, GLfloat factor, GLfloat units);
-bool ValidateReleaseShaderCompiler(ValidationContext *context);
-bool ValidateSampleCoverage(ValidationContext *context, GLclampf value, GLboolean invert);
-bool ValidateScissor(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height);
-bool ValidateShaderBinary(ValidationContext *context,
+bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name);
+bool ValidateHint(Context *context, GLenum target, GLenum mode);
+bool ValidateIsBuffer(Context *context, GLuint buffer);
+bool ValidateIsFramebuffer(Context *context, GLuint framebuffer);
+bool ValidateIsProgram(Context *context, GLuint program);
+bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer);
+bool ValidateIsShader(Context *context, GLuint shader);
+bool ValidateIsTexture(Context *context, GLuint texture);
+bool ValidatePixelStorei(Context *context, GLenum pname, GLint param);
+bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units);
+bool ValidateReleaseShaderCompiler(Context *context);
+bool ValidateSampleCoverage(Context *context, GLclampf value, GLboolean invert);
+bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height);
+bool ValidateShaderBinary(Context *context,
                           GLsizei n,
                           const GLuint *shaders,
                           GLenum binaryformat,
                           const void *binary,
                           GLsizei length);
-bool ValidateShaderSource(ValidationContext *context,
+bool ValidateShaderSource(Context *context,
                           GLuint shader,
                           GLsizei count,
                           const GLchar *const *string,
                           const GLint *length);
-bool ValidateStencilFunc(ValidationContext *context, GLenum func, GLint ref, GLuint mask);
-bool ValidateStencilFuncSeparate(ValidationContext *context,
+bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask);
+bool ValidateStencilFuncSeparate(Context *context,
                                  GLenum face,
                                  GLenum func,
                                  GLint ref,
                                  GLuint mask);
-bool ValidateStencilMask(ValidationContext *context, GLuint mask);
-bool ValidateStencilMaskSeparate(ValidationContext *context, GLenum face, GLuint mask);
-bool ValidateStencilOp(ValidationContext *context, GLenum fail, GLenum zfail, GLenum zpass);
-bool ValidateStencilOpSeparate(ValidationContext *context,
+bool ValidateStencilMask(Context *context, GLuint mask);
+bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask);
+bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass);
+bool ValidateStencilOpSeparate(Context *context,
                                GLenum face,
                                GLenum fail,
                                GLenum zfail,
                                GLenum zpass);
-bool ValidateUniform1f(ValidationContext *context, GLint location, GLfloat x);
-bool ValidateUniform1fv(ValidationContext *context,
-                        GLint location,
-                        GLsizei count,
-                        const GLfloat *v);
-bool ValidateUniform1i(ValidationContext *context, GLint location, GLint x);
-bool ValidateUniform2f(ValidationContext *context, GLint location, GLfloat x, GLfloat y);
-bool ValidateUniform2fv(ValidationContext *context,
-                        GLint location,
-                        GLsizei count,
-                        const GLfloat *v);
-bool ValidateUniform2i(ValidationContext *context, GLint location, GLint x, GLint y);
-bool ValidateUniform2iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v);
-bool ValidateUniform3f(ValidationContext *context, GLint location, GLfloat x, GLfloat y, GLfloat z);
-bool ValidateUniform3fv(ValidationContext *context,
-                        GLint location,
-                        GLsizei count,
-                        const GLfloat *v);
-bool ValidateUniform3i(ValidationContext *context, GLint location, GLint x, GLint y, GLint z);
-bool ValidateUniform3iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v);
-bool ValidateUniform4f(ValidationContext *context,
+bool ValidateUniform1f(Context *context, GLint location, GLfloat x);
+bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v);
+bool ValidateUniform1i(Context *context, GLint location, GLint x);
+bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y);
+bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v);
+bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y);
+bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v);
+bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z);
+bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v);
+bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z);
+bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v);
+bool ValidateUniform4f(Context *context,
                        GLint location,
                        GLfloat x,
                        GLfloat y,
                        GLfloat z,
                        GLfloat w);
-bool ValidateUniform4fv(ValidationContext *context,
-                        GLint location,
-                        GLsizei count,
-                        const GLfloat *v);
-bool ValidateUniform4i(ValidationContext *context,
-                       GLint location,
-                       GLint x,
-                       GLint y,
-                       GLint z,
-                       GLint w);
-bool ValidateUniform4iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v);
-bool ValidateUniformMatrix2fv(ValidationContext *context,
+bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v);
+bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w);
+bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v);
+bool ValidateUniformMatrix2fv(Context *context,
+                              GLint location,
+                              GLsizei count,
+                              GLboolean transpose,
+                              const GLfloat *value);
+bool ValidateUniformMatrix3fv(Context *context,
                               GLint location,
                               GLsizei count,
                               GLboolean transpose,
                               const GLfloat *value);
-bool ValidateUniformMatrix3fv(ValidationContext *context,
-                              GLint location,
-                              GLsizei count,
-                              GLboolean transpose,
-                              const GLfloat *value);
-bool ValidateUniformMatrix4fv(ValidationContext *context,
+bool ValidateUniformMatrix4fv(Context *context,
                               GLint location,
                               GLsizei count,
                               GLboolean transpose,
                               const GLfloat *value);
-bool ValidateValidateProgram(ValidationContext *context, GLuint program);
-bool ValidateVertexAttrib1f(ValidationContext *context, GLuint index, GLfloat x);
-bool ValidateVertexAttrib1fv(ValidationContext *context, GLuint index, const GLfloat *values);
-bool ValidateVertexAttrib2f(ValidationContext *context, GLuint index, GLfloat x, GLfloat y);
-bool ValidateVertexAttrib2fv(ValidationContext *context, GLuint index, const GLfloat *values);
-bool ValidateVertexAttrib3f(ValidationContext *context,
-                            GLuint index,
-                            GLfloat x,
-                            GLfloat y,
-                            GLfloat z);
-bool ValidateVertexAttrib3fv(ValidationContext *context, GLuint index, const GLfloat *values);
-bool ValidateVertexAttrib4f(ValidationContext *context,
+bool ValidateValidateProgram(Context *context, GLuint program);
+bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x);
+bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values);
+bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y);
+bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values);
+bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z);
+bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values);
+bool ValidateVertexAttrib4f(Context *context,
                             GLuint index,
                             GLfloat x,
                             GLfloat y,
                             GLfloat z,
                             GLfloat w);
-bool ValidateVertexAttrib4fv(ValidationContext *context, GLuint index, const GLfloat *values);
-bool ValidateViewport(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height);
-bool ValidateDrawElements(ValidationContext *context,
+bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values);
+bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height);
+bool ValidateDrawElements(Context *context,
                           GLenum mode,
                           GLsizei count,
                           GLenum type,
                           const void *indices);
 
-bool ValidateDrawArrays(ValidationContext *context, GLenum mode, GLint first, GLsizei count);
+bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count);
 
 bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
                                                  GLenum target,
                                                  GLenum attachment,
                                                  GLenum pname,
                                                  GLint *params);
-bool ValidateGetProgramiv(ValidationContext *context, GLuint program, GLenum pname, GLint *params);
+bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params);
 
-bool ValidateCopyTexImage2D(ValidationContext *context,
-                            GLenum target,
+bool ValidateCopyTexImage2D(Context *context,
+                            TextureTarget target,
                             GLint level,
                             GLenum internalformat,
                             GLint x,
                             GLint y,
                             GLsizei width,
                             GLsizei height,
                             GLint border);
 
 bool ValidateCopyTexSubImage2D(Context *context,
-                               GLenum target,
+                               TextureTarget target,
                                GLint level,
                                GLint xoffset,
                                GLint yoffset,
                                GLint x,
                                GLint y,
                                GLsizei width,
                                GLsizei height);
 
@@ -638,58 +620,61 @@ bool ValidateEnable(Context *context, GL
 bool ValidateFramebufferRenderbuffer(Context *context,
                                      GLenum target,
                                      GLenum attachment,
                                      GLenum renderbuffertarget,
                                      GLuint renderbuffer);
 bool ValidateFramebufferTexture2D(Context *context,
                                   GLenum target,
                                   GLenum attachment,
-                                  GLenum textarget,
+                                  TextureTarget textarget,
                                   GLuint texture,
                                   GLint level);
 bool ValidateGenBuffers(Context *context, GLint n, GLuint *buffers);
-bool ValidateGenerateMipmap(Context *context, GLenum target);
+bool ValidateGenerateMipmap(Context *context, TextureType target);
 bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *framebuffers);
 bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *renderbuffers);
 bool ValidateGenTextures(Context *context, GLint n, GLuint *textures);
-bool ValidateGetBufferParameteriv(ValidationContext *context,
+bool ValidateGetBufferParameteriv(Context *context,
                                   BufferBinding target,
                                   GLenum pname,
                                   GLint *params);
 bool ValidateGetRenderbufferParameteriv(Context *context,
                                         GLenum target,
                                         GLenum pname,
                                         GLint *params);
 bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params);
-bool ValidateGetTexParameterfv(Context *context, GLenum target, GLenum pname, GLfloat *params);
-bool ValidateGetTexParameteriv(Context *context, GLenum target, GLenum pname, GLint *params);
+bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params);
+bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params);
 bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params);
 bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params);
 bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params);
 bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params);
 bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer);
 bool ValidateIsEnabled(Context *context, GLenum cap);
 bool ValidateLinkProgram(Context *context, GLuint program);
 bool ValidateReadPixels(Context *context,
                         GLint x,
                         GLint y,
                         GLsizei width,
                         GLsizei height,
                         GLenum format,
                         GLenum type,
                         void *pixels);
-bool ValidateTexParameterf(Context *context, GLenum target, GLenum pname, GLfloat param);
-bool ValidateTexParameterfv(Context *context, GLenum target, GLenum pname, const GLfloat *params);
-bool ValidateTexParameteri(Context *context, GLenum target, GLenum pname, GLint param);
-bool ValidateTexParameteriv(Context *context, GLenum target, GLenum pname, const GLint *params);
-bool ValidateUniform1iv(ValidationContext *context,
-                        GLint location,
-                        GLsizei count,
-                        const GLint *value);
+bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param);
+bool ValidateTexParameterfv(Context *context,
+                            TextureType target,
+                            GLenum pname,
+                            const GLfloat *params);
+bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param);
+bool ValidateTexParameteriv(Context *context,
+                            TextureType target,
+                            GLenum pname,
+                            const GLint *params);
+bool ValidateUniform1iv(Context *context, GLint location, GLsizei count, const GLint *value);
 bool ValidateUseProgram(Context *context, GLuint program);
 
 // Extension validation
 bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences);
 bool ValidateFinishFenceNV(Context *context, GLuint fence);
 bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences);
 bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params);
 bool ValidateGetGraphicsResetStatusEXT(Context *context);
@@ -697,17 +682,17 @@ bool ValidateGetTranslatedShaderSourceAN
                                             GLuint shader,
                                             GLsizei bufsize,
                                             GLsizei *length,
                                             GLchar *source);
 bool ValidateIsFenceNV(Context *context, GLuint fence);
 bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition);
 bool ValidateTestFenceNV(Context *context, GLuint fence);
 bool ValidateTexStorage2DEXT(Context *context,
-                             GLenum target,
+                             TextureType type,
                              GLsizei levels,
                              GLenum internalformat,
                              GLsizei width,
                              GLsizei height);
 bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor);
 bool ValidateTexImage3DOES(Context *context,
                            GLenum target,
                            GLint level,
@@ -721,17 +706,17 @@ bool ValidateTexImage3DOES(Context *cont
                            const void *pixels);
 bool ValidatePopGroupMarkerEXT(Context *context);
 bool ValidateTexStorage1DEXT(Context *context,
                              GLenum target,
                              GLsizei levels,
                              GLenum internalformat,
                              GLsizei width);
 bool ValidateTexStorage3DEXT(Context *context,
-                             GLenum target,
+                             TextureType target,
                              GLsizei levels,
                              GLenum internalformat,
                              GLsizei width,
                              GLsizei height,
                              GLsizei depth);
 
 }  // namespace gl
 
--- a/gfx/angle/checkout/src/libANGLE/validationES3.cpp
+++ b/gfx/angle/checkout/src/libANGLE/validationES3.cpp
@@ -61,24 +61,24 @@ bool ValidateFramebufferTextureMultiview
 
     return true;
 }
 
 bool ValidateFramebufferTextureMultiviewLevelAndFormat(Context *context,
                                                        Texture *texture,
                                                        GLint level)
 {
-    GLenum texTarget = texture->getTarget();
-    if (!ValidMipLevel(context, texTarget, level))
+    TextureType type = texture->getType();
+    if (!ValidMipLevel(context, type, level))
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
         return false;
     }
 
-    const auto &format = texture->getFormat(texTarget, level);
+    const auto &format = texture->getFormat(NonCubeTextureTypeToTarget(type), level);
     if (format.info->compressed)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), CompressedTexturesNotAttachable);
         return false;
     }
     return true;
 }
 
@@ -132,17 +132,17 @@ bool ValidateGenOrDeleteCountES3(Context
         return false;
     }
     return true;
 }
 
 }  // anonymous namespace
 
 static bool ValidateTexImageFormatCombination(gl::Context *context,
-                                              GLenum target,
+                                              TextureType target,
                                               GLenum internalFormat,
                                               GLenum format,
                                               GLenum type)
 {
 
     // The type and format are valid if any supported internal format has that type and format
     if (!ValidES3Format(format))
     {
@@ -166,17 +166,17 @@ static bool ValidateTexImageFormatCombin
         return false;
     }
 
     // From the ES 3.0 spec section 3.8.3:
     // Textures with a base internal format of DEPTH_COMPONENT or DEPTH_STENCIL are supported by
     // texture image specification commands only if target is TEXTURE_2D, TEXTURE_2D_ARRAY, or
     // TEXTURE_CUBE_MAP.Using these formats in conjunction with any other target will result in an
     // INVALID_OPERATION error.
-    if (target == GL_TEXTURE_3D && (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL))
+    if (target == TextureType::_3D && (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL))
     {
         context->handleError(InvalidOperation() << "Format cannot be GL_DEPTH_COMPONENT or "
                                                    "GL_DEPTH_STENCIL if target is "
                                                    "GL_TEXTURE_3D");
         return false;
     }
 
     // Check if this is a valid format combination to load texture data
@@ -193,35 +193,37 @@ static bool ValidateTexImageFormatCombin
         context->handleError(InvalidOperation() << "Unsupported internal format.");
         return false;
     }
 
     return true;
 }
 
 bool ValidateES3TexImageParametersBase(Context *context,
-                                       GLenum target,
+                                       TextureTarget target,
                                        GLint level,
                                        GLenum internalformat,
                                        bool isCompressed,
                                        bool isSubImage,
                                        GLint xoffset,
                                        GLint yoffset,
                                        GLint zoffset,
                                        GLsizei width,
                                        GLsizei height,
                                        GLsizei depth,
                                        GLint border,
                                        GLenum format,
                                        GLenum type,
                                        GLsizei imageSize,
                                        const void *pixels)
 {
+    TextureType texType = TextureTargetToType(target);
+
     // Validate image size
-    if (!ValidImageSizeParameters(context, target, level, width, height, depth, isSubImage))
+    if (!ValidImageSizeParameters(context, texType, level, width, height, depth, isSubImage))
     {
         context->handleError(InvalidValue());
         return false;
     }
 
     // Verify zero border
     if (border != 0)
     {
@@ -235,89 +237,83 @@ bool ValidateES3TexImageParametersBase(C
         std::numeric_limits<GLsizei>::max() - zoffset < depth)
     {
         context->handleError(InvalidValue());
         return false;
     }
 
     const gl::Caps &caps = context->getCaps();
 
-    switch (target)
+    switch (texType)
     {
-        case GL_TEXTURE_2D:
+        case TextureType::_2D:
             if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
                 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
             {
                 context->handleError(InvalidValue());
                 return false;
             }
             break;
 
-        case GL_TEXTURE_RECTANGLE_ANGLE:
+        case TextureType::Rectangle:
             ASSERT(level == 0);
             if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
                 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
             {
                 context->handleError(InvalidValue());
                 return false;
             }
             if (isCompressed)
             {
                 context->handleError(InvalidEnum()
                                      << "Rectangle texture cannot have a compressed format.");
                 return false;
             }
             break;
 
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-        case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+        case TextureType::CubeMap:
             if (!isSubImage && width != height)
             {
                 context->handleError(InvalidValue());
                 return false;
             }
 
             if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level))
             {
                 context->handleError(InvalidValue());
                 return false;
             }
             break;
 
-        case GL_TEXTURE_3D:
+        case TextureType::_3D:
             if (static_cast<GLuint>(width) > (caps.max3DTextureSize >> level) ||
                 static_cast<GLuint>(height) > (caps.max3DTextureSize >> level) ||
                 static_cast<GLuint>(depth) > (caps.max3DTextureSize >> level))
             {
                 context->handleError(InvalidValue());
                 return false;
             }
             break;
 
-        case GL_TEXTURE_2D_ARRAY:
+        case TextureType::_2DArray:
             if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
                 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level) ||
                 static_cast<GLuint>(depth) > caps.maxArrayTextureLayers)
             {
                 context->handleError(InvalidValue());
                 return false;
             }
             break;
 
         default:
             context->handleError(InvalidEnum());
             return false;
     }
 
-    gl::Texture *texture =
-        context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+    gl::Texture *texture = context->getTargetTexture(texType);
     if (!texture)
     {
         context->handleError(InvalidOperation());
         return false;
     }
 
     if (texture->getImmutableFormat() && !isSubImage)
     {
@@ -379,25 +375,26 @@ bool ValidateES3TexImageParametersBase(C
         }
 
         if (!actualFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
         {
             context->handleError(InvalidEnum());
             return false;
         }
 
-        if (target == GL_TEXTURE_3D)
+        if (texType == TextureType::_3D)
         {
             context->handleError(InvalidOperation());
             return false;
         }
     }
     else
     {
-        if (!ValidateTexImageFormatCombination(context, target, actualInternalFormat, format, type))
+        if (!ValidateTexImageFormatCombination(context, texType, actualInternalFormat, format,
+                                               type))
         {
             return false;
         }
     }
 
     // Validate sub image parameters
     if (isSubImage)
     {
@@ -433,17 +430,17 @@ bool ValidateES3TexImageParametersBase(C
             context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack) == nullptr)
         {
             ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
             return false;
         }
     }
 
     GLenum sizeCheckFormat = isSubImage ? format : internalformat;
-    if (!ValidImageDataSize(context, target, width, height, depth, sizeCheckFormat, type, pixels,
+    if (!ValidImageDataSize(context, texType, width, height, depth, sizeCheckFormat, type, pixels,
                             imageSize))
     {
         return false;
     }
 
     // Check for pixel unpack buffer related API errors
     gl::Buffer *pixelUnpackBuffer =
         context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
@@ -472,17 +469,17 @@ bool ValidateES3TexImageParametersBase(C
             return false;
         }
     }
 
     return true;
 }
 
 bool ValidateES3TexImage2DParameters(Context *context,
-                                     GLenum target,
+                                     TextureTarget target,
                                      GLint level,
                                      GLenum internalformat,
                                      bool isCompressed,
                                      bool isSubImage,
                                      GLint xoffset,
                                      GLint yoffset,
                                      GLint zoffset,
                                      GLsizei width,
@@ -501,17 +498,17 @@ bool ValidateES3TexImage2DParameters(Con
     }
 
     return ValidateES3TexImageParametersBase(context, target, level, internalformat, isCompressed,
                                              isSubImage, xoffset, yoffset, zoffset, width, height,
                                              depth, border, format, type, imageSize, pixels);
 }
 
 bool ValidateES3TexImage3DParameters(Context *context,
-                                     GLenum target,
+                                     TextureType target,
                                      GLint level,
                                      GLenum internalformat,
                                      bool isCompressed,
                                      bool isSubImage,
                                      GLint xoffset,
                                      GLint yoffset,
                                      GLint zoffset,
                                      GLsizei width,
@@ -524,26 +521,27 @@ bool ValidateES3TexImage3DParameters(Con
                                      const void *pixels)
 {
     if (!ValidTexture3DDestinationTarget(context, target))
     {
         context->handleError(InvalidEnum());
         return false;
     }
 
-    if (IsETC2EACFormat(format) && target != GL_TEXTURE_2D_ARRAY)
+    if (IsETC2EACFormat(format) && target != TextureType::_2DArray)
     {
         // ES 3.1, Section 8.7, page 169.
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), InternalFormatRequiresTexture2DArray);
         return false;
     }
 
-    return ValidateES3TexImageParametersBase(context, target, level, internalformat, isCompressed,
-                                             isSubImage, xoffset, yoffset, zoffset, width, height,
-                                             depth, border, format, type, bufSize, pixels);
+    return ValidateES3TexImageParametersBase(context, NonCubeTextureTypeToTarget(target), level,
+                                             internalformat, isCompressed, isSubImage, xoffset,
+                                             yoffset, zoffset, width, height, depth, border, format,
+                                             type, bufSize, pixels);
 }
 
 struct EffectiveInternalFormatInfo
 {
     GLenum effectiveFormat;
     GLenum destFormat;
     GLuint minRedBits;
     GLuint maxRedBits;
@@ -778,18 +776,18 @@ static bool IsValidES3CopyTexImageCombin
             return false;
         }
     }
 
     return true;  // A conversion function exists, and no rule in the specification has precluded
                   // conversion between these formats.
 }
 
-bool ValidateES3CopyTexImageParametersBase(ValidationContext *context,
-                                           GLenum target,
+bool ValidateES3CopyTexImageParametersBase(Context *context,
+                                           TextureTarget target,
                                            GLint level,
                                            GLenum internalformat,
                                            bool isSubImage,
                                            GLint xoffset,
                                            GLint yoffset,
                                            GLint zoffset,
                                            GLint x,
                                            GLint y,
@@ -805,25 +803,23 @@ bool ValidateES3CopyTexImageParametersBa
         return false;
     }
     ASSERT(textureFormat.valid() || !isSubImage);
 
     const auto &state            = context->getGLState();
     gl::Framebuffer *framebuffer = state.getReadFramebuffer();
     GLuint readFramebufferID     = framebuffer->id();
 
-    if (framebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
+    if (!ValidateFramebufferComplete(context, framebuffer, true))
     {
-        context->handleError(InvalidFramebufferOperation());
         return false;
     }
 
-    if (readFramebufferID != 0 && framebuffer->getSamples(context) != 0)
+    if (readFramebufferID != 0 && !ValidateFramebufferNotMultisampled(context, framebuffer))
     {
-        context->handleError(InvalidOperation());
         return false;
     }
 
     const FramebufferAttachment *source = framebuffer->getReadColorbuffer();
 
     if (isSubImage)
     {
         if (!IsValidES3CopyTexImageCombination(*textureFormat.info, *source->getFormat().info,
@@ -844,18 +840,18 @@ bool ValidateES3CopyTexImageParametersBa
             return false;
         }
     }
 
     // If width or height is zero, it is a no-op.  Return false without setting an error.
     return (width > 0 && height > 0);
 }
 
-bool ValidateES3CopyTexImage2DParameters(ValidationContext *context,
-                                         GLenum target,
+bool ValidateES3CopyTexImage2DParameters(Context *context,
+                                         TextureTarget target,
                                          GLint level,
                                          GLenum internalformat,
                                          bool isSubImage,
                                          GLint xoffset,
                                          GLint yoffset,
                                          GLint zoffset,
                                          GLint x,
                                          GLint y,
@@ -869,18 +865,18 @@ bool ValidateES3CopyTexImage2DParameters
         return false;
     }
 
     return ValidateES3CopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
                                                  xoffset, yoffset, zoffset, x, y, width, height,
                                                  border);
 }
 
-bool ValidateES3CopyTexImage3DParameters(ValidationContext *context,
-                                         GLenum target,
+bool ValidateES3CopyTexImage3DParameters(Context *context,
+                                         TextureType target,
                                          GLint level,
                                          GLenum internalformat,
                                          bool isSubImage,
                                          GLint xoffset,
                                          GLint yoffset,
                                          GLint zoffset,
                                          GLint x,
                                          GLint y,
@@ -889,102 +885,102 @@ bool ValidateES3CopyTexImage3DParameters
                                          GLint border)
 {
     if (!ValidTexture3DDestinationTarget(context, target))
     {
         context->handleError(InvalidEnum());
         return false;
     }
 
-    return ValidateES3CopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
-                                                 xoffset, yoffset, zoffset, x, y, width, height,
-                                                 border);
+    return ValidateES3CopyTexImageParametersBase(context, NonCubeTextureTypeToTarget(target), level,
+                                                 internalformat, isSubImage, xoffset, yoffset,
+                                                 zoffset, x, y, width, height, border);
 }
 
 bool ValidateES3TexStorageParametersBase(Context *context,
-                                         GLenum target,
+                                         TextureType target,
                                          GLsizei levels,
                                          GLenum internalformat,
                                          GLsizei width,
                                          GLsizei height,
                                          GLsizei depth)
 {
     if (width < 1 || height < 1 || depth < 1 || levels < 1)
     {
         context->handleError(InvalidValue());
         return false;
     }
 
     GLsizei maxDim = std::max(width, height);
-    if (target != GL_TEXTURE_2D_ARRAY)
+    if (target != TextureType::_2DArray)
     {
         maxDim = std::max(maxDim, depth);
     }
 
     if (levels > gl::log2(maxDim) + 1)
     {
         context->handleError(InvalidOperation());
         return false;
     }
 
     const gl::Caps &caps = context->getCaps();
 
     switch (target)
     {
-        case GL_TEXTURE_2D:
+        case TextureType::_2D:
         {
             if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
                 static_cast<GLuint>(height) > caps.max2DTextureSize)
             {
                 context->handleError(InvalidValue());
                 return false;
             }
         }
         break;
 
-        case GL_TEXTURE_RECTANGLE_ANGLE:
+        case TextureType::Rectangle:
         {
             if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
                 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
             {
                 context->handleError(InvalidValue());
                 return false;
             }
         }
         break;
 
-        case GL_TEXTURE_CUBE_MAP:
+        case TextureType::CubeMap:
         {
             if (width != height)
             {
                 context->handleError(InvalidValue());
                 return false;
             }
 
             if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize)
             {
                 context->handleError(InvalidValue());
                 return false;
             }
         }
         break;
 
-        case GL_TEXTURE_3D:
+        case TextureType::_3D:
         {
             if (static_cast<GLuint>(width) > caps.max3DTextureSize ||
                 static_cast<GLuint>(height) > caps.max3DTextureSize ||
                 static_cast<GLuint>(depth) > caps.max3DTextureSize)
             {
                 context->handleError(InvalidValue());
                 return false;
             }
         }
         break;
 
-        case GL_TEXTURE_2D_ARRAY:
+        case TextureType::_2DArray:
         {
             if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
                 static_cast<GLuint>(height) > caps.max2DTextureSize ||
                 static_cast<GLuint>(depth) > caps.maxArrayTextureLayers)
             {
                 context->handleError(InvalidValue());
                 return false;
             }
@@ -1017,27 +1013,27 @@ bool ValidateES3TexStorageParametersBase
     }
 
     if (!formatInfo.sized)
     {
         context->handleError(InvalidEnum());
         return false;
     }
 
-    if (formatInfo.compressed && target == GL_TEXTURE_RECTANGLE_ANGLE)
+    if (formatInfo.compressed && target == TextureType::Rectangle)
     {
         context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
         return false;
     }
 
     return true;
 }
 
 bool ValidateES3TexStorage2DParameters(Context *context,
-                                       GLenum target,
+                                       TextureType target,
                                        GLsizei levels,
                                        GLenum internalformat,
                                        GLsizei width,
                                        GLsizei height,
                                        GLsizei depth)
 {
     if (!ValidTexture2DTarget(context, target))
     {
@@ -1045,17 +1041,17 @@ bool ValidateES3TexStorage2DParameters(C
         return false;
     }
 
     return ValidateES3TexStorageParametersBase(context, target, levels, internalformat, width,
                                                height, depth);
 }
 
 bool ValidateES3TexStorage3DParameters(Context *context,
-                                       GLenum target,
+                                       TextureType target,
                                        GLsizei levels,
                                        GLenum internalformat,
                                        GLsizei width,
                                        GLsizei height,
                                        GLsizei depth)
 {
     if (!ValidTexture3DTarget(context, target))
     {
@@ -1136,35 +1132,35 @@ bool ValidateFramebufferTextureLayer(Con
         {
             context->handleError(InvalidValue());
             return false;
         }
 
         gl::Texture *tex = context->getTexture(texture);
         ASSERT(tex);
 
-        switch (tex->getTarget())
+        switch (tex->getType())
         {
-            case GL_TEXTURE_2D_ARRAY:
+            case TextureType::_2DArray:
             {
                 if (level > gl::log2(caps.max2DTextureSize))
                 {
                     context->handleError(InvalidValue());
                     return false;
                 }
 
                 if (static_cast<GLuint>(layer) >= caps.maxArrayTextureLayers)
                 {
                     context->handleError(InvalidValue());
                     return false;
                 }
             }
             break;
 
-            case GL_TEXTURE_3D:
+            case TextureType::_3D:
             {
                 if (level > gl::log2(caps.max3DTextureSize))
                 {
                     context->handleError(InvalidValue());
                     return false;
                 }
 
                 if (static_cast<GLuint>(layer) >= caps.max3DTextureSize)
@@ -1175,17 +1171,17 @@ bool ValidateFramebufferTextureLayer(Con
             }
             break;
 
             default:
                 context->handleError(InvalidOperation());
                 return false;
         }
 
-        const auto &format = tex->getFormat(tex->getTarget(), level);
+        const auto &format = tex->getFormat(NonCubeTextureTypeToTarget(tex->getType()), level);
         if (format.info->compressed)
         {
             context->handleError(InvalidOperation());
             return false;
         }
     }
 
     return true;
@@ -1235,27 +1231,26 @@ bool ValidateInvalidateSubFramebuffer(Co
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
         return false;
     }
 
     return ValidateInvalidateFramebuffer(context, target, numAttachments, attachments);
 }
 
-bool ValidateClearBuffer(ValidationContext *context)
+bool ValidateClearBuffer(Context *context)
 {
     if (context->getClientMajorVersion() < 3)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
         return false;
     }
 
-    if (context->getGLState().getDrawFramebuffer()->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
+    if (!ValidateFramebufferComplete(context, context->getGLState().getDrawFramebuffer(), true))
     {
-        context->handleError(InvalidFramebufferOperation());
         return false;
     }
 
     return true;
 }
 
 bool ValidateDrawRangeElements(Context *context,
                                GLenum mode,
@@ -1284,25 +1279,22 @@ bool ValidateDrawRangeElements(Context *
 
     // Skip range checks for no-op calls.
     if (count <= 0)
     {
         return true;
     }
 
     // Use the parameter buffer to retrieve and cache the index range.
-    const auto &params        = context->getParams<HasIndexRange>();
-    const auto &indexRangeOpt = params.getIndexRange();
-    if (!indexRangeOpt.valid())
-    {
-        // Unexpected error.
-        return false;
-    }
-
-    if (indexRangeOpt.value().end > end || indexRangeOpt.value().start < start)
+    const DrawCallParams &params = context->getParams<DrawCallParams>();
+    ANGLE_VALIDATION_TRY(params.ensureIndexRangeResolved(context));
+
+    const IndexRange &indexRange = params.getIndexRange();
+
+    if (indexRange.end > end || indexRange.start < start)
     {
         // GL spec says that behavior in this case is undefined - generating an error is fine.
         context->handleError(InvalidOperation() << "Indices are out of the start, end range.");
         return false;
     }
     return true;
 }
 
@@ -1364,17 +1356,17 @@ bool ValidateReadBuffer(Context *context
             return false;
         }
     }
 
     return true;
 }
 
 bool ValidateCompressedTexImage3D(Context *context,
-                                  GLenum target,
+                                  TextureType target,
                                   GLint level,
                                   GLenum internalformat,
                                   GLsizei width,
                                   GLsizei height,
                                   GLsizei depth,
                                   GLint border,
                                   GLsizei imageSize,
                                   const void *data)
@@ -1413,17 +1405,17 @@ bool ValidateCompressedTexImage3D(Contex
     }
     if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
     {
         context->handleError(InvalidValue());
         return false;
     }
 
     // 3D texture target validation
-    if (target != GL_TEXTURE_3D && target != GL_TEXTURE_2D_ARRAY)
+    if (target != TextureType::_3D && target != TextureType::_2DArray)
     {
         context->handleError(InvalidEnum() << "Must specify a valid 3D texture destination target");
         return false;
     }
 
     // validateES3TexImageFormat sets the error code if there is an error
     if (!ValidateES3TexImage3DParameters(context, target, level, internalformat, true, false, 0, 0,
                                          0, width, height, depth, border, GL_NONE, GL_NONE, -1,
@@ -1431,17 +1423,17 @@ bool ValidateCompressedTexImage3D(Contex
     {
         return false;
     }
 
     return true;
 }
 
 bool ValidateCompressedTexImage3DRobustANGLE(Context *context,
-                                             GLenum target,
+                                             TextureType target,
                                              GLint level,
                                              GLenum internalformat,
                                              GLsizei width,
                                              GLsizei height,
                                              GLsizei depth,
                                              GLint border,
                                              GLsizei imageSize,
                                              GLsizei dataSize,
@@ -1724,20 +1716,17 @@ bool ValidateBlitFramebuffer(Context *co
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
         return false;
     }
 
     return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
                                              dstX1, dstY1, mask, filter);
 }
 
-bool ValidateClearBufferiv(ValidationContext *context,
-                           GLenum buffer,
-                           GLint drawbuffer,
-                           const GLint *value)
+bool ValidateClearBufferiv(Context *context, GLenum buffer, GLint drawbuffer, const GLint *value)
 {
     switch (buffer)
     {
         case GL_COLOR:
             if (drawbuffer < 0 ||
                 static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
             {
                 context->handleError(InvalidValue());
@@ -1765,20 +1754,17 @@ bool ValidateClearBufferiv(ValidationCon
         default:
             context->handleError(InvalidEnum());
             return false;
     }
 
     return ValidateClearBuffer(context);
 }
 
-bool ValidateClearBufferuiv(ValidationContext *context,
-                            GLenum buffer,
-                            GLint drawbuffer,
-                            const GLuint *value)
+bool ValidateClearBufferuiv(Context *context, GLenum buffer, GLint drawbuffer, const GLuint *value)
 {
     switch (buffer)
     {
         case GL_COLOR:
             if (drawbuffer < 0 ||
                 static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
             {
                 context->handleError(InvalidValue());
@@ -1798,20 +1784,17 @@ bool ValidateClearBufferuiv(ValidationCo
         default:
             context->handleError(InvalidEnum());
             return false;
     }
 
     return ValidateClearBuffer(context);
 }
 
-bool ValidateClearBufferfv(ValidationContext *context,
-                           GLenum buffer,
-                           GLint drawbuffer,
-                           const GLfloat *value)
+bool ValidateClearBufferfv(Context *context, GLenum buffer, GLint drawbuffer, const GLfloat *value)
 {
     switch (buffer)
     {
         case GL_COLOR:
             if (drawbuffer < 0 ||
                 static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
             {
                 context->handleError(InvalidValue());
@@ -1840,17 +1823,17 @@ bool ValidateClearBufferfv(ValidationCon
         default:
             context->handleError(InvalidEnum());
             return false;
     }
 
     return ValidateClearBuffer(context);
 }
 
-bool ValidateClearBufferfi(ValidationContext *context,
+bool ValidateClearBufferfi(Context *context,
                            GLenum buffer,
                            GLint drawbuffer,
                            GLfloat depth,
                            GLint stencil)
 {
     switch (buffer)
     {
         case GL_DEPTH_STENCIL:
@@ -1864,29 +1847,29 @@ bool ValidateClearBufferfi(ValidationCon
         default:
             context->handleError(InvalidEnum());
             return false;
     }
 
     return ValidateClearBuffer(context);
 }
 
-bool ValidateDrawBuffers(ValidationContext *context, GLsizei n, const GLenum *bufs)
+bool ValidateDrawBuffers(Context *context, GLsizei n, const GLenum *bufs)
 {
     if (context->getClientMajorVersion() < 3)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
         return false;
     }
 
     return ValidateDrawBuffersBase(context, n, bufs);
 }
 
 bool ValidateCopyTexSubImage3D(Context *context,
-                               GLenum target,
+                               TextureType target,
                                GLint level,
                                GLint xoffset,
                                GLint yoffset,
                                GLint zoffset,
                                GLint x,
                                GLint y,
                                GLsizei width,
                                GLsizei height)
@@ -1897,17 +1880,17 @@ bool ValidateCopyTexSubImage3D(Context *
         return false;
     }
 
     return ValidateES3CopyTexImage3DParameters(context, target, level, GL_NONE, true, xoffset,
                                                yoffset, zoffset, x, y, width, height, 0);
 }
 
 bool ValidateTexImage3D(Context *context,
-                        GLenum target,
+                        TextureType target,
                         GLint level,
                         GLint internalformat,
                         GLsizei width,
                         GLsizei height,
                         GLsizei depth,
                         GLint border,
                         GLenum format,
                         GLenum type,
@@ -1920,17 +1903,17 @@ bool ValidateTexImage3D(Context *context
     }
 
     return ValidateES3TexImage3DParameters(context, target, level, internalformat, false, false, 0,
                                            0, 0, width, height, depth, border, format, type, -1,
                                            pixels);
 }
 
 bool ValidateTexImage3DRobustANGLE(Context *context,
-                                   GLenum target,
+                                   TextureType target,
                                    GLint level,
                                    GLint internalformat,
                                    GLsizei width,
                                    GLsizei height,
                                    GLsizei depth,
                                    GLint border,
                                    GLenum format,
                                    GLenum type,
@@ -1949,17 +1932,17 @@ bool ValidateTexImage3DRobustANGLE(Conte
     }
 
     return ValidateES3TexImage3DParameters(context, target, level, internalformat, false, false, 0,
                                            0, 0, width, height, depth, border, format, type,
                                            bufSize, pixels);
 }
 
 bool ValidateTexSubImage3D(Context *context,
-                           GLenum target,
+                           TextureType target,
                            GLint level,
                            GLint xoffset,
                            GLint yoffset,
                            GLint zoffset,
                            GLsizei width,
                            GLsizei height,
                            GLsizei depth,
                            GLenum format,
@@ -1973,17 +1956,17 @@ bool ValidateTexSubImage3D(Context *cont
     }
 
     return ValidateES3TexImage3DParameters(context, target, level, GL_NONE, false, true, xoffset,
                                            yoffset, zoffset, width, height, depth, 0, format, type,
                                            -1, pixels);
 }
 
 bool ValidateTexSubImage3DRobustANGLE(Context *context,
-                                      GLenum target,
+                                      TextureType target,
                                       GLint level,
                                       GLint xoffset,
                                       GLint yoffset,
                                       GLint zoffset,
                                       GLsizei width,
                                       GLsizei height,
                                       GLsizei depth,
                                       GLenum format,
@@ -2003,17 +1986,17 @@ bool ValidateTexSubImage3DRobustANGLE(Co
     }
 
     return ValidateES3TexImage3DParameters(context, target, level, GL_NONE, false, true, xoffset,
                                            yoffset, zoffset, width, height, depth, 0, format, type,
                                            bufSize, pixels);
 }
 
 bool ValidateCompressedTexSubImage3D(Context *context,
-                                     GLenum target,
+                                     TextureType target,
                                      GLint level,
                                      GLint xoffset,
                                      GLint yoffset,
                                      GLint zoffset,
                                      GLsizei width,
                                      GLsizei height,
                                      GLsizei depth,
                                      GLenum format,
@@ -2057,17 +2040,17 @@ bool ValidateCompressedTexSubImage3D(Con
         context->handleError(InvalidValue());
         return false;
     }
 
     return true;
 }
 
 bool ValidateCompressedTexSubImage3DRobustANGLE(Context *context,
-                                                GLenum target,
+                                                TextureType target,
                                                 GLint level,
                                                 GLint xoffset,
                                                 GLint yoffset,
                                                 GLint zoffset,
                                                 GLsizei width,
                                                 GLsizei height,
                                                 GLsizei depth,
                                                 GLenum format,
@@ -2206,26 +2189,30 @@ bool ValidateGetBufferPointervRobustANGL
                                           GLsizei *length,
                                           void **params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateGetBufferPointervBase(context, target, pname, length, params))
+    GLsizei numParams = 0;
+
+    if (!ValidateGetBufferPointervBase(context, target, pname, &numParams, params))
     {
         return false;
     }
 
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
     {
         return false;
     }
 
+    SetRobustLengthParam(length, numParams);
+
     return true;
 }
 
 bool ValidateUnmapBuffer(Context *context, BufferBinding target)
 {
     if (context->getClientMajorVersion() < 3)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
@@ -2259,20 +2246,17 @@ bool ValidateFlushMappedBufferRange(Cont
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
         return false;
     }
 
     return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
 }
 
-bool ValidateIndexedStateQuery(ValidationContext *context,
-                               GLenum pname,
-                               GLuint index,
-                               GLsizei *length)
+bool ValidateIndexedStateQuery(Context *context, GLenum pname, GLuint index, GLsizei *length)
 {
     if (length)
     {
         *length = 0;
     }
 
     GLenum nativeType;
     unsigned int numParams;
@@ -2408,27 +2392,27 @@ bool ValidateIndexedStateQuery(Validatio
     if (length)
     {
         *length = 1;
     }
 
     return true;
 }
 
-bool ValidateGetIntegeri_v(ValidationContext *context, GLenum target, GLuint index, GLint *data)
+bool ValidateGetIntegeri_v(Context *context, GLenum target, GLuint index, GLint *data)
 {
     if (context->getClientVersion() < ES_3_0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
         return false;
     }
     return ValidateIndexedStateQuery(context, target, index, nullptr);
 }
 
-bool ValidateGetIntegeri_vRobustANGLE(ValidationContext *context,
+bool ValidateGetIntegeri_vRobustANGLE(Context *context,
                                       GLenum target,
                                       GLuint index,
                                       GLsizei bufSize,
                                       GLsizei *length,
                                       GLint *data)
 {
     if (context->getClientVersion() < ES_3_0)
     {
@@ -2436,40 +2420,44 @@ bool ValidateGetIntegeri_vRobustANGLE(Va
         return false;
     }
 
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateIndexedStateQuery(context, target, index, length))
+    GLsizei numParams = 0;
+
+    if (!ValidateIndexedStateQuery(context, target, index, &numParams))
     {
         return false;
     }
 
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
     {
         return false;
     }
 
+    SetRobustLengthParam(length, numParams);
+
     return true;
 }
 
-bool ValidateGetInteger64i_v(ValidationContext *context, GLenum target, GLuint index, GLint64 *data)
+bool ValidateGetInteger64i_v(Context *context, GLenum target, GLuint index, GLint64 *data)
 {
     if (context->getClientVersion() < ES_3_0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
         return false;
     }
     return ValidateIndexedStateQuery(context, target, index, nullptr);
 }
 
-bool ValidateGetInteger64i_vRobustANGLE(ValidationContext *context,
+bool ValidateGetInteger64i_vRobustANGLE(Context *context,
                                         GLenum target,
                                         GLuint index,
                                         GLsizei bufSize,
                                         GLsizei *length,
                                         GLint64 *data)
 {
     if (context->getClientVersion() < ES_3_0)
     {
@@ -2477,30 +2465,34 @@ bool ValidateGetInteger64i_vRobustANGLE(
         return false;
     }
 
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateIndexedStateQuery(context, target, index, length))
+    GLsizei numParams = 0;
+
+    if (!ValidateIndexedStateQuery(context, target, index, &numParams))
     {
         return false;
     }
 
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
     {
         return false;
     }
 
+    SetRobustLengthParam(length, numParams);
+
     return true;
 }
 
-bool ValidateCopyBufferSubData(ValidationContext *context,
+bool ValidateCopyBufferSubData(Context *context,
                                BufferBinding readTarget,
                                BufferBinding writeTarget,
                                GLintptr readOffset,
                                GLintptr writeOffset,
                                GLsizeiptr size)
 {
     if (context->getClientMajorVersion() < 3)
     {
@@ -2526,16 +2518,24 @@ bool ValidateCopyBufferSubData(Validatio
     // Verify that readBuffer and writeBuffer are not currently mapped
     if (readBuffer->isMapped() || writeBuffer->isMapped())
     {
         context->handleError(InvalidOperation()
                              << "Cannot call CopyBufferSubData on a mapped buffer");
         return false;
     }
 
+    if (context->getExtensions().webglCompatibility &&
+        (readBuffer->isBoundForTransformFeedbackAndOtherUse() ||
+         writeBuffer->isBoundForTransformFeedbackAndOtherUse()))
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
+        return false;
+    }
+
     CheckedNumeric<GLintptr> checkedReadOffset(readOffset);
     CheckedNumeric<GLintptr> checkedWriteOffset(writeOffset);
     CheckedNumeric<GLintptr> checkedSize(size);
 
     auto checkedReadSum  = checkedReadOffset + checkedSize;
     auto checkedWriteSum = checkedWriteOffset + checkedSize;
 
     if (!checkedReadSum.IsValid() || !checkedWriteSum.IsValid() ||
@@ -2619,17 +2619,17 @@ bool ValidateGetStringi(Context *context
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
             return false;
     }
 
     return true;
 }
 
-bool ValidateRenderbufferStorageMultisample(ValidationContext *context,
+bool ValidateRenderbufferStorageMultisample(Context *context,
                                             GLenum target,
                                             GLsizei samples,
                                             GLenum internalformat,
                                             GLsizei width,
                                             GLsizei height)
 {
     if (context->getClientMajorVersion() < 3)
     {
@@ -2665,17 +2665,17 @@ bool ValidateRenderbufferStorageMultisam
             InvalidOperation()
             << "Samples must not be greater than maximum supported value for the format.");
         return false;
     }
 
     return true;
 }
 
-bool ValidateVertexAttribIPointer(ValidationContext *context,
+bool ValidateVertexAttribIPointer(Context *context,
                                   GLuint index,
                                   GLint size,
                                   GLenum type,
                                   GLsizei stride,
                                   const void *pointer)
 {
     if (context->getClientMajorVersion() < 3)
     {
@@ -2776,17 +2776,17 @@ bool ValidateGetSynciv(Context *context,
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
             return false;
     }
 
     return true;
 }
 
-bool ValidateDrawElementsInstanced(ValidationContext *context,
+bool ValidateDrawElementsInstanced(Context *context,
                                    GLenum mode,
                                    GLsizei count,
                                    GLenum type,
                                    const void *indices,
                                    GLsizei instanceCount)
 {
     if (context->getClientMajorVersion() < 3)
     {
@@ -2818,19 +2818,19 @@ bool ValidateFramebufferTextureMultiview
         {
             context->handleError(InvalidValue() << "baseViewIndex cannot be less than 0.");
             return false;
         }
 
         Texture *tex = context->getTexture(texture);
         ASSERT(tex);
 
-        switch (tex->getTarget())
+        switch (tex->getType())
         {
-            case GL_TEXTURE_2D_ARRAY:
+            case TextureType::_2DArray:
             {
                 const Caps &caps = context->getCaps();
                 if (static_cast<GLuint>(baseViewIndex + numViews) > caps.maxArrayTextureLayers)
                 {
                     context->handleError(InvalidValue() << "baseViewIndex+numViews cannot be "
                                                            "greater than "
                                                            "GL_MAX_ARRAY_TEXTURE_LAYERS.");
                     return false;
@@ -2877,19 +2877,19 @@ bool ValidateFramebufferTextureMultiview
                                      << "viewportOffsets cannot contain negative values.");
                 return false;
             }
         }
 
         Texture *tex = context->getTexture(texture);
         ASSERT(tex);
 
-        switch (tex->getTarget())
+        switch (tex->getType())
         {
-            case GL_TEXTURE_2D:
+            case TextureType::_2D:
                 break;
             default:
                 context->handleError(InvalidOperation()
                                      << "Texture's target must be GL_TEXTURE_2D.");
                 return false;
         }
 
         if (!ValidateFramebufferTextureMultiviewLevelAndFormat(context, tex, level))
@@ -3634,17 +3634,17 @@ bool ValidateVertexAttribDivisor(Context
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
         return false;
     }
 
     return ValidateVertexAttribIndex(context, index);
 }
 
 bool ValidateTexStorage2D(Context *context,
-                          GLenum target,
+                          TextureType target,
                           GLsizei levels,
                           GLenum internalformat,
                           GLsizei width,
                           GLsizei height)
 {
     if (context->getClientMajorVersion() < 3)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
@@ -3656,17 +3656,17 @@ bool ValidateTexStorage2D(Context *conte
     {
         return false;
     }
 
     return true;
 }
 
 bool ValidateTexStorage3D(Context *context,
-                          GLenum target,
+                          TextureType target,
                           GLsizei levels,
                           GLenum internalformat,
                           GLsizei width,
                           GLsizei height,
                           GLsizei depth)
 {
     if (context->getClientMajorVersion() < 3)
     {
@@ -3678,17 +3678,17 @@ bool ValidateTexStorage3D(Context *conte
                                            depth))
     {
         return false;
     }
 
     return true;
 }
 
-bool ValidateGetBufferParameteri64v(ValidationContext *context,
+bool ValidateGetBufferParameteri64v(Context *context,
                                     BufferBinding target,
                                     GLenum pname,
                                     GLint64 *params)
 {
     return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
 }
 
 bool ValidateGetSamplerParameterfv(Context *context, GLuint sampler, GLenum pname, GLfloat *params)
--- a/gfx/angle/checkout/src/libANGLE/validationES3.h
+++ b/gfx/angle/checkout/src/libANGLE/validationES3.h
@@ -12,19 +12,18 @@
 #include "libANGLE/PackedGLEnums.h"
 
 #include <GLES3/gl3.h>
 
 namespace gl
 {
 class Context;
 struct IndexRange;
-class ValidationContext;
 
-bool ValidateES3TexImageParametersBase(ValidationContext *context,
+bool ValidateES3TexImageParametersBase(Context *context,
                                        GLenum target,
                                        GLint level,
                                        GLenum internalformat,
                                        bool isCompressed,
                                        bool isSubImage,
                                        GLint xoffset,
                                        GLint yoffset,
                                        GLint zoffset,
@@ -33,25 +32,25 @@ bool ValidateES3TexImageParametersBase(V
                                        GLsizei depth,
                                        GLint border,
                                        GLenum format,
                                        GLenum type,
                                        GLsizei imageSize,
                                        const void *pixels);
 
 bool ValidateES3TexStorageParameters(Context *context,
-                                     GLenum target,
+                                     TextureType target,
                                      GLsizei levels,
                                      GLenum internalformat,
                                      GLsizei width,
                                      GLsizei height,
                                      GLsizei depth);
 
 bool ValidateES3TexImage2DParameters(Context *context,
-                                     GLenum target,
+                                     TextureTarget target,
                                      GLint level,
                                      GLenum internalformat,
                                      bool isCompressed,
                                      bool isSubImage,
                                      GLint xoffset,
                                      GLint yoffset,
                                      GLint zoffset,
                                      GLsizei width,
@@ -59,93 +58,93 @@ bool ValidateES3TexImage2DParameters(Con
                                      GLsizei depth,
                                      GLint border,
                                      GLenum format,
                                      GLenum type,
                                      GLsizei imageSize,
                                      const void *pixels);
 
 bool ValidateES3TexImage3DParameters(Context *context,
-                                     GLenum target,
+                                     TextureType target,
                                      GLint level,
                                      GLenum internalformat,
                                      bool isCompressed,
                                      bool isSubImage,
                                      GLint xoffset,
                                      GLint yoffset,
                                      GLint zoffset,
                                      GLsizei width,
                                      GLsizei height,
                                      GLsizei depth,
                                      GLint border,
                                      GLenum format,
                                      GLenum type,
                                      GLsizei bufSize,
                                      const void *pixels);
 
-bool ValidateES3CopyTexImageParametersBase(ValidationContext *context,
+bool ValidateES3CopyTexImageParametersBase(Context *context,
                                            GLenum target,
                                            GLint level,
                                            GLenum internalformat,
                                            bool isSubImage,
                                            GLint xoffset,
                                            GLint yoffset,
                                            GLint zoffset,
                                            GLint x,
                                            GLint y,
                                            GLsizei width,
                                            GLsizei height,
                                            GLint border);
 
-bool ValidateES3CopyTexImage2DParameters(ValidationContext *context,
-                                         GLenum target,
+bool ValidateES3CopyTexImage2DParameters(Context *context,
+                                         TextureTarget target,
                                          GLint level,
                                          GLenum internalformat,
                                          bool isSubImage,
                                          GLint xoffset,
                                          GLint yoffset,
                                          GLint zoffset,
                                          GLint x,
                                          GLint y,
                                          GLsizei width,
                                          GLsizei height,
                                          GLint border);
 
-bool ValidateES3CopyTexImage3DParameters(ValidationContext *context,
-                                         GLenum target,
+bool ValidateES3CopyTexImage3DParameters(Context *context,
+                                         TextureType target,
                                          GLint level,
                                          GLenum internalformat,
                                          bool isSubImage,
                                          GLint xoffset,
                                          GLint yoffset,
                                          GLint zoffset,
                                          GLint x,
                                          GLint y,
                                          GLsizei width,
                                          GLsizei height,
                                          GLint border);
 
 bool ValidateES3TexStorageParametersBase(Context *context,
-                                         GLenum target,
+                                         TextureType target,
                                          GLsizei levels,
                                          GLenum internalformat,
                                          GLsizei width,
                                          GLsizei height,
                                          GLsizei depth);
 
 bool ValidateES3TexStorage2DParameters(Context *context,
-                                       GLenum target,
+                                       TextureType target,
                                        GLsizei levels,
                                        GLenum internalformat,
                                        GLsizei width,
                                        GLsizei height,
                                        GLsizei depth);
 
 bool ValidateES3TexStorage3DParameters(Context *context,
-                                       GLenum target,
+                                       TextureType target,
                                        GLsizei levels,
                                        GLenum internalformat,
                                        GLsizei width,
                                        GLsizei height,
                                        GLsizei depth);
 
 bool ValidateBeginQuery(Context *context, GLenum target, GLuint id);
 
@@ -171,42 +170,42 @@ bool ValidateInvalidateSubFramebuffer(Co
                                       GLenum target,
                                       GLsizei numAttachments,
                                       const GLenum *attachments,
                                       GLint x,
                                       GLint y,
                                       GLsizei width,
                                       GLsizei height);
 
-bool ValidateClearBuffer(ValidationContext *context);
+bool ValidateClearBuffer(Context *context);
 
 bool ValidateDrawRangeElements(Context *context,
                                GLenum mode,
                                GLuint start,
                                GLuint end,
                                GLsizei count,
                                GLenum type,
                                const void *indices);
 
 bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint *params);
 
 bool ValidateReadBuffer(Context *context, GLenum mode);
 
 bool ValidateCompressedTexImage3D(Context *context,
-                                  GLenum target,
+                                  TextureType target,
                                   GLint level,
                                   GLenum internalformat,
                                   GLsizei width,
                                   GLsizei height,
                                   GLsizei depth,
                                   GLint border,
                                   GLsizei imageSize,
                                   const void *data);
 bool ValidateCompressedTexImage3DRobustANGLE(Context *context,
-                                             GLenum target,
+                                             TextureType target,
                                              GLint level,
                                              GLenum internalformat,
                                              GLsizei width,
                                              GLsizei height,
                                              GLsizei depth,
                                              GLint border,
                                              GLsizei imageSize,
                                              GLsizei dataSize,
@@ -241,106 +240,97 @@ bool ValidateBlitFramebuffer(Context *co
                              GLint srcX1,
                              GLint srcY1,
                              GLint dstX0,
                              GLint dstY0,
                              GLint dstX1,
                              GLint dstY1,
                              GLbitfield mask,
                              GLenum filter);
-bool ValidateClearBufferiv(ValidationContext *context,
-                           GLenum buffer,
-                           GLint drawbuffer,
-                           const GLint *value);
-bool ValidateClearBufferuiv(ValidationContext *context,
-                            GLenum buffer,
-                            GLint drawbuffer,
-                            const GLuint *value);
-bool ValidateClearBufferfv(ValidationContext *context,
-                           GLenum buffer,
-                           GLint drawbuffer,
-                           const GLfloat *value);
-bool ValidateClearBufferfi(ValidationContext *context,
+bool ValidateClearBufferiv(Context *context, GLenum buffer, GLint drawbuffer, const GLint *value);
+bool ValidateClearBufferuiv(Context *context, GLenum buffer, GLint drawbuffer, const GLuint *value);
+bool ValidateClearBufferfv(Context *context, GLenum buffer, GLint drawbuffer, const GLfloat *value);
+bool ValidateClearBufferfi(Context *context,
                            GLenum buffer,
                            GLint drawbuffer,
                            GLfloat depth,
                            GLint stencil);
-bool ValidateDrawBuffers(ValidationContext *context, GLsizei n, const GLenum *bufs);
+bool ValidateDrawBuffers(Context *context, GLsizei n, const GLenum *bufs);
 bool ValidateCopyTexSubImage3D(Context *context,
-                               GLenum target,
+                               TextureType target,
                                GLint level,
                                GLint xoffset,
                                GLint yoffset,
                                GLint zoffset,
                                GLint x,
                                GLint y,
                                GLsizei width,
                                GLsizei height);
 bool ValidateTexImage3D(Context *context,
-                        GLenum target,
+                        TextureType target,
                         GLint level,
                         GLint internalformat,
                         GLsizei width,
                         GLsizei height,
                         GLsizei depth,
                         GLint border,
                         GLenum format,
                         GLenum type,
                         const void *pixels);
 bool ValidateTexImage3DRobustANGLE(Context *context,
-                                   GLenum target,
+                                   TextureType target,
                                    GLint level,
                                    GLint internalformat,
                                    GLsizei width,
                                    GLsizei height,
                                    GLsizei depth,
                                    GLint border,
                                    GLenum format,
                                    GLenum type,
                                    GLsizei bufSize,
                                    const void *pixels);
 bool ValidateTexSubImage3D(Context *context,
-                           GLenum target,
+                           TextureType target,
                            GLint level,
                            GLint xoffset,
                            GLint yoffset,
                            GLint zoffset,
                            GLsizei width,
                            GLsizei height,
                            GLsizei depth,
                            GLenum format,
                            GLenum type,
                            const void *pixels);
 bool ValidateTexSubImage3DRobustANGLE(Context *context,
-                                      GLenum target,
+                                      TextureType target,
                                       GLint level,
                                       GLint xoffset,
                                       GLint yoffset,
                                       GLint zoffset,
                                       GLsizei width,
                                       GLsizei height,
                                       GLsizei depth,
                                       GLenum format,
                                       GLenum type,
                                       GLsizei bufSize,
                                       const void *pixels);
 bool ValidateCompressedTexSubImage3D(Context *context,
-                                     GLenum target,
+                                     TextureType target,
                                      GLint level,
                                      GLint xoffset,
                                      GLint yoffset,
                                      GLint zoffset,
                                      GLsizei width,
                                      GLsizei height,
                                      GLsizei depth,
                                      GLenum format,
                                      GLsizei imageSize,
                                      const void *data);
 bool ValidateCompressedTexSubImage3DRobustANGLE(Context *context,
-                                                GLenum target,
+                                                TextureType target,
                                                 GLint level,
                                                 GLint xoffset,
                                                 GLint yoffset,
                                                 GLint zoffset,
                                                 GLsizei width,
                                                 GLsizei height,
                                                 GLsizei depth,
                                                 GLenum format,
@@ -372,68 +362,62 @@ bool ValidateMapBufferRange(Context *con
                             GLintptr offset,
                             GLsizeiptr length,
                             GLbitfield access);
 bool ValidateFlushMappedBufferRange(Context *context,
                                     BufferBinding target,
                                     GLintptr offset,
                                     GLsizeiptr length);
 
-bool ValidateIndexedStateQuery(ValidationContext *context,
-                               GLenum pname,
-                               GLuint index,
-                               GLsizei *length);
-bool ValidateGetIntegeri_v(ValidationContext *context, GLenum target, GLuint index, GLint *data);
-bool ValidateGetIntegeri_vRobustANGLE(ValidationContext *context,
+bool ValidateIndexedStateQuery(Context *context, GLenum pname, GLuint index, GLsizei *length);
+bool ValidateGetIntegeri_v(Context *context, GLenum target, GLuint index, GLint *data);
+bool ValidateGetIntegeri_vRobustANGLE(Context *context,
                                       GLenum target,
                                       GLuint index,
                                       GLsizei bufSize,
                                       GLsizei *length,
                                       GLint *data);
-bool ValidateGetInteger64i_v(ValidationContext *context,
-                             GLenum target,
-                             GLuint index,
-                             GLint64 *data);
-bool ValidateGetInteger64i_vRobustANGLE(ValidationContext *context,
+bool ValidateGetInteger64i_v(Context *context, GLenum target, GLuint index, GLint64 *data);
+bool ValidateGetInteger64i_vRobustANGLE(Context *context,
                                         GLenum target,
                                         GLuint index,
                                         GLsizei bufSize,
                                         GLsizei *length,
                                         GLint64 *data);
 
-bool ValidateCopyBufferSubData(ValidationContext *context,
+bool ValidateCopyBufferSubData(Context *context,
                                BufferBinding readTarget,
                                BufferBinding writeTarget,
                                GLintptr readOffset,
                                GLintptr writeOffset,
                                GLsizeiptr size);
 
 bool ValidateGetStringi(Context *context, GLenum name, GLuint index);
-bool ValidateRenderbufferStorageMultisample(ValidationContext *context,
+bool ValidateRenderbufferStorageMultisample(Context *context,
                                             GLenum target,
                                             GLsizei samples,
                                             GLenum internalformat,
                                             GLsizei width,
                                             GLsizei height);
 
-bool ValidateVertexAttribIPointer(ValidationContext *context,
+bool ValidateVertexAttribIPointer(Context *context,
                                   GLuint index,
                                   GLint size,
                                   GLenum type,
                                   GLsizei stride,
                                   const void *pointer);
 
 bool ValidateGetSynciv(Context *context,
                        GLsync sync,
                        GLenum pname,
                        GLsizei bufSize,
                        GLsizei *length,
                        GLint *values);
 
-bool ValidateDrawElementsInstanced(ValidationContext *context,
+bool ValidateDrawElementsInstanced(Context *context,
                                    GLenum mode,
                                    GLsizei count,
                                    GLenum type,
                                    const void *indices,
                                    GLsizei instanceCount);
 
 bool ValidateFramebufferTextureMultiviewLayeredANGLE(Context *context,
                                                      GLenum target,
@@ -566,32 +550,32 @@ bool ValidateDeleteSync(Context *context
 bool ValidateClientWaitSync(Context *context, GLsync sync, GLbitfield flags, GLuint64 timeout);
 bool ValidateWaitSync(Context *context, GLsync sync, GLbitfield flags, GLuint64 timeout);
 bool ValidateGetInteger64v(Context *context, GLenum pname, GLint64 *params);
 
 bool ValidateIsSampler(Context *context, GLuint sampler);
 bool ValidateBindSampler(Context *context, GLuint unit, GLuint sampler);
 bool ValidateVertexAttribDivisor(Context *context, GLuint index, GLuint divisor);
 bool ValidateTexStorage2D(Context *context,
-                          GLenum target,
+                          TextureType target,
                           GLsizei levels,
                           GLenum internalformat,
                           GLsizei width,
                           GLsizei height);
 bool ValidateTexStorage3D(Context *context,
-                          GLenum target,
+                          TextureType target,
                           GLsizei levels,
                           GLenum internalformat,
                           GLsizei width,
                           GLsizei height,
                           GLsizei depth);
 
 bool ValidateGetVertexAttribIiv(Context *context, GLuint index, GLenum pname, GLint *params);
 bool ValidateGetVertexAttribIuiv(Context *context, GLuint index, GLenum pname, GLuint *params);
-bool ValidateGetBufferParameteri64v(ValidationContext *context,
+bool ValidateGetBufferParameteri64v(Context *context,
                                     BufferBinding target,
                                     GLenum pname,
                                     GLint64 *params);
 bool ValidateSamplerParameteri(Context *context, GLuint sampler, GLenum pname, GLint param);
 bool ValidateSamplerParameteriv(Context *context,
                                 GLuint sampler,
                                 GLenum pname,
                                 const GLint *params);
--- a/gfx/angle/checkout/src/libANGLE/validationES31.cpp
+++ b/gfx/angle/checkout/src/libANGLE/validationES31.cpp
@@ -276,56 +276,56 @@ bool ValidateProgramResourceIndex(const 
             return (index < static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()));
 
         default:
             UNREACHABLE();
             return false;
     }
 }
 
-bool ValidateProgramUniform(gl::Context *context,
+bool ValidateProgramUniform(Context *context,
                             GLenum valueType,
                             GLuint program,
                             GLint location,
                             GLsizei count)
 {
     // Check for ES31 program uniform entry points
     if (context->getClientVersion() < Version(3, 1))
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
     }
 
     const LinkedUniform *uniform = nullptr;
-    gl::Program *programObject   = GetValidProgram(context, program);
+    Program *programObject       = GetValidProgram(context, program);
     return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
            ValidateUniformValue(context, valueType, uniform->type);
 }
 
-bool ValidateProgramUniformMatrix(gl::Context *context,
+bool ValidateProgramUniformMatrix(Context *context,
                                   GLenum valueType,
                                   GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   GLboolean transpose)
 {
     // Check for ES31 program uniform entry points
     if (context->getClientVersion() < Version(3, 1))
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
     }
 
     const LinkedUniform *uniform = nullptr;
-    gl::Program *programObject   = GetValidProgram(context, program);
+    Program *programObject       = GetValidProgram(context, program);
     return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
            ValidateUniformMatrixValue(context, valueType, uniform->type);
 }
 
-bool ValidateVertexAttribFormatCommon(ValidationContext *context,
+bool ValidateVertexAttribFormatCommon(Context *context,
                                       GLuint attribIndex,
                                       GLint size,
                                       GLenum type,
                                       GLuint relativeOffset,
                                       GLboolean pureInteger)
 {
     if (context->getClientVersion() < ES_3_1)
     {
@@ -384,26 +384,29 @@ bool ValidateGetBooleani_vRobustANGLE(Co
         return false;
     }
 
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
     }
 
-    if (!ValidateIndexedStateQuery(context, target, index, length))
+    GLsizei numParams = 0;
+
+    if (!ValidateIndexedStateQuery(context, target, index, &numParams))
     {
         return false;
     }
 
-    if (!ValidateRobustBufferSize(context, bufSize, *length))
+    if (!ValidateRobustBufferSize(context, bufSize, numParams))
     {
         return false;
     }
 
+    SetRobustLengthParam(length, numParams);
     return true;
 }
 
 bool ValidateDrawIndirectBase(Context *context, GLenum mode, const void *indirect)
 {
     if (context->getClientVersion() < ES_3_1)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
@@ -421,17 +424,17 @@ bool ValidateDrawIndirectBase(Context *c
     // An INVALID_OPERATION error is generated if zero is bound to VERTEX_ARRAY_BINDING,
     // DRAW_INDIRECT_BUFFER or to any enabled vertex array.
     if (!state.getVertexArrayId())
     {
         context->handleError(InvalidOperation() << "zero is bound to VERTEX_ARRAY_BINDING");
         return false;
     }
 
-    gl::Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
+    Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
     if (!drawIndirectBuffer)
     {
         context->handleError(InvalidOperation() << "zero is bound to DRAW_INDIRECT_BUFFER");
         return false;
     }
 
     // An INVALID_VALUE error is generated if indirect is not a multiple of the size, in basic
     // machine units, of uint.
@@ -458,29 +461,29 @@ bool ValidateDrawIndirectBase(Context *c
     }
 
     return true;
 }
 
 bool ValidateDrawArraysIndirect(Context *context, GLenum mode, const void *indirect)
 {
     const State &state                          = context->getGLState();
-    gl::TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
+    TransformFeedback *curTransformFeedback     = state.getCurrentTransformFeedback();
     if (curTransformFeedback && curTransformFeedback->isActive() &&
         !curTransformFeedback->isPaused())
     {
         // An INVALID_OPERATION error is generated if transform feedback is active and not paused.
         context->handleError(InvalidOperation() << "transform feedback is active and not paused.");
         return false;
     }
 
     if (!ValidateDrawIndirectBase(context, mode, indirect))
         return false;
 
-    gl::Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
+    Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
     CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
     // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawArraysIndirectCommand
     // which's size is 4 * sizeof(uint).
     auto checkedSum = checkedOffset + 4 * sizeof(GLuint);
     if (!checkedSum.IsValid() ||
         checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
     {
         context->handleError(
@@ -494,27 +497,27 @@ bool ValidateDrawArraysIndirect(Context 
 
 bool ValidateDrawElementsIndirect(Context *context, GLenum mode, GLenum type, const void *indirect)
 {
     if (!ValidateDrawElementsBase(context, type))
         return false;
 
     const State &state             = context->getGLState();
     const VertexArray *vao         = state.getVertexArray();
-    gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
+    Buffer *elementArrayBuffer     = vao->getElementArrayBuffer().get();
     if (!elementArrayBuffer)
     {
         context->handleError(InvalidOperation() << "zero is bound to ELEMENT_ARRAY_BUFFER");
         return false;
     }
 
     if (!ValidateDrawIndirectBase(context, mode, indirect))
         return false;
 
-    gl::Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
+    Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
     CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
     // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawElementsIndirectCommand
     // which's size is 5 * sizeof(uint).
     auto checkedSum = checkedOffset + 5 * sizeof(GLuint);
     if (!checkedSum.IsValid() ||
         checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
     {
         context->handleError(
@@ -645,17 +648,17 @@ bool ValidateProgramUniform1iv(Context *
     // Check for ES31 program uniform entry points
     if (context->getClientVersion() < Version(3, 1))
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
     }
 
     const LinkedUniform *uniform = nullptr;
-    gl::Program *programObject   = GetValidProgram(context, program);
+    Program *programObject       = GetValidProgram(context, program);
     return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
            ValidateUniform1ivValue(context, uniform->type, count, value);
 }
 
 bool ValidateProgramUniform2iv(Context *context,
                                GLuint program,
                                GLint location,
                                GLsizei count,
@@ -849,46 +852,47 @@ bool ValidateProgramUniformMatrix4x3fv(C
                                        GLboolean transpose,
                                        const GLfloat *value)
 {
     return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x3, program, location, count,
                                         transpose);
 }
 
 bool ValidateGetTexLevelParameterBase(Context *context,
-                                      GLenum target,
+                                      TextureTarget target,
                                       GLint level,
                                       GLenum pname,
                                       GLsizei *length)
 {
     if (context->getClientVersion() < ES_3_1)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
     }
 
     if (length)
     {
         *length = 0;
     }
 
-    if (!ValidTexLevelDestinationTarget(context, target))
+    TextureType type = TextureTargetToType(target);
+
+    if (!ValidTexLevelDestinationTarget(context, type))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
         return false;
     }
 
-    if (context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target) ==
-        nullptr)
+    if (context->getTargetTexture(type) == nullptr)
     {
         context->handleError(InvalidEnum() << "No texture bound.");
         return false;
     }
 
-    if (!ValidMipLevel(context, target, level))
+    if (!ValidMipLevel(context, type, level))
     {
         context->handleError(InvalidValue());
         return false;
     }
 
     switch (pname)
     {
         case GL_TEXTURE_RED_TYPE:
@@ -923,48 +927,72 @@ bool ValidateGetTexLevelParameterBase(Co
     if (length)
     {
         *length = 1;
     }
     return true;
 }
 
 bool ValidateGetTexLevelParameterfv(Context *context,
-                                    GLenum target,
+                                    TextureTarget target,
                                     GLint level,
                                     GLenum pname,
                                     GLfloat *params)
 {
     return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
 }
 
+bool ValidateGetTexLevelParameterfvRobustANGLE(Context *context,
+                                               TextureTarget target,
+                                               GLint level,
+                                               GLenum pname,
+                                               GLsizei bufSize,
+                                               GLsizei *length,
+                                               GLfloat *params)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
 bool ValidateGetTexLevelParameteriv(Context *context,
-                                    GLenum target,
+                                    TextureTarget target,
                                     GLint level,
                                     GLenum pname,
                                     GLint *params)
 {
     return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
 }
 
+bool ValidateGetTexLevelParameterivRobustANGLE(Context *context,
+                                               TextureTarget target,
+                                               GLint level,
+                                               GLenum pname,
+                                               GLsizei bufSize,
+                                               GLsizei *length,
+                                               GLint *params)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
 bool ValidateTexStorage2DMultisample(Context *context,
-                                     GLenum target,
+                                     TextureType target,
                                      GLsizei samples,
                                      GLint internalFormat,
                                      GLsizei width,
                                      GLsizei height,
                                      GLboolean fixedSampleLocations)
 {
     if (context->getClientVersion() < ES_3_1)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
     }
 
-    if (target != GL_TEXTURE_2D_MULTISAMPLE)
+    if (target != TextureType::_2DMultisample)
     {
         context->handleError(InvalidEnum() << "Target must be TEXTURE_2D_MULTISAMPLE.");
         return false;
     }
 
     if (width < 1 || height < 1)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
@@ -1042,26 +1070,39 @@ bool ValidateGetMultisamplefv(Context *c
 
     if (pname != GL_SAMPLE_POSITION)
     {
         context->handleError(InvalidEnum() << "Pname must be SAMPLE_POSITION.");
         return false;
     }
 
     Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
+    GLint samples            = 0;
+    ANGLE_VALIDATION_TRY(framebuffer->getSamples(context, &samples));
 
-    if (index >= static_cast<GLuint>(framebuffer->getSamples(context)))
+    if (index >= static_cast<GLuint>(samples))
     {
         context->handleError(InvalidValue() << "Index must be less than the value of SAMPLES.");
         return false;
     }
 
     return true;
 }
 
+bool ValidateGetMultisamplefvRobustANGLE(Context *context,
+                                         GLenum pname,
+                                         GLuint index,
+                                         GLsizei bufSize,
+                                         GLsizei *length,
+                                         GLfloat *val)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
 bool ValidateFramebufferParameteri(Context *context, GLenum target, GLenum pname, GLint param)
 {
     if (context->getClientVersion() < ES_3_1)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
     }
 
@@ -1162,16 +1203,27 @@ bool ValidateGetFramebufferParameteriv(C
     if (framebuffer->id() == 0)
     {
         context->handleError(InvalidOperation() << "Default framebuffer is bound to target.");
         return false;
     }
     return true;
 }
 
+bool ValidateGetFramebufferParameterivRobustANGLE(Context *context,
+                                                  GLenum target,
+                                                  GLenum pname,
+                                                  GLsizei bufSize,
+                                                  GLsizei *length,
+                                                  GLint *params)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
 bool ValidateGetProgramResourceIndex(Context *context,
                                      GLuint program,
                                      GLenum programInterface,
                                      const GLchar *name)
 {
     if (context->getClientVersion() < ES_3_1)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
@@ -1189,17 +1241,17 @@ bool ValidateGetProgramResourceIndex(Con
         context->handleError(InvalidEnum() << "Invalid program interface: 0x" << std::hex
                                            << std::uppercase << programInterface);
         return false;
     }
 
     return true;
 }
 
-bool ValidateBindVertexBuffer(ValidationContext *context,
+bool ValidateBindVertexBuffer(Context *context,
                               GLuint bindingIndex,
                               GLuint buffer,
                               GLintptr offset,
                               GLsizei stride)
 {
     if (context->getClientVersion() < ES_3_1)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
@@ -1239,17 +1291,17 @@ bool ValidateBindVertexBuffer(Validation
     {
         context->handleError(InvalidOperation() << "Default vertex array buffer is bound.");
         return false;
     }
 
     return true;
 }
 
-bool ValidateVertexBindingDivisor(ValidationContext *context, GLuint bindingIndex, GLuint divisor)
+bool ValidateVertexBindingDivisor(Context *context, GLuint bindingIndex, GLuint divisor)
 {
     if (context->getClientVersion() < ES_3_1)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
     }
 
     const Caps &caps = context->getCaps();
@@ -1266,39 +1318,37 @@ bool ValidateVertexBindingDivisor(Valida
     {
         context->handleError(InvalidOperation() << "Default vertex array object is bound.");
         return false;
     }
 
     return true;
 }
 
-bool ValidateVertexAttribFormat(ValidationContext *context,
+bool ValidateVertexAttribFormat(Context *context,
                                 GLuint attribindex,
                                 GLint size,
                                 GLenum type,
                                 GLboolean normalized,
                                 GLuint relativeoffset)
 {
     return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset,
                                             false);
 }
 
-bool ValidateVertexAttribIFormat(ValidationContext *context,
+bool ValidateVertexAttribIFormat(Context *context,
                                  GLuint attribindex,
                                  GLint size,
                                  GLenum type,
                                  GLuint relativeoffset)
 {
     return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset, true);
 }
 
-bool ValidateVertexAttribBinding(ValidationContext *context,
-                                 GLuint attribIndex,
-                                 GLuint bindingIndex)
+bool ValidateVertexAttribBinding(Context *context, GLuint attribIndex, GLuint bindingIndex)
 {
     if (context->getClientVersion() < ES_3_1)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
     }
 
     // [OpenGL ES 3.1] Section 10.3.1 page 243:
@@ -1377,17 +1427,17 @@ bool ValidateDispatchCompute(Context *co
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
     }
 
     const State &state = context->getGLState();
     Program *program   = state.getProgram();
 
-    if (program == nullptr || !program->hasLinkedComputeShader())
+    if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
         return false;
     }
 
     const Caps &caps = context->getCaps();
     if (numGroupsX > caps.maxComputeWorkGroupCount[0])
     {
@@ -1420,17 +1470,17 @@ bool ValidateDispatchComputeIndirect(Con
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
     }
 
     const State &state = context->getGLState();
     Program *program   = state.getProgram();
 
-    if (program == nullptr || !program->hasLinkedComputeShader())
+    if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
         return false;
     }
 
     if (indirect < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
@@ -1438,17 +1488,17 @@ bool ValidateDispatchComputeIndirect(Con
     }
 
     if ((indirect & (sizeof(GLuint) - 1)) != 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), OffsetMustBeMultipleOfUint);
         return false;
     }
 
-    gl::Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
+    Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
     if (!dispatchIndirectBuffer)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), DispatchIndirectBufferNotBound);
         return false;
     }
 
     CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
     auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
@@ -1688,16 +1738,28 @@ bool ValidateGetProgramInterfaceiv(Conte
                     << "MAX_NUM_ACTIVE_VARIABLES requires a buffer or block interface.");
                 return false;
         }
     }
 
     return true;
 }
 
+bool ValidateGetProgramInterfaceivRobustANGLE(Context *context,
+                                              GLuint program,
+                                              GLenum programInterface,
+                                              GLenum pname,
+                                              GLsizei bufSize,
+                                              GLsizei *length,
+                                              GLint *params)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
 static bool ValidateGenOrDeleteES31(Context *context, GLint n)
 {
     if (context->getClientVersion() < ES_3_1)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
     }
 
@@ -1750,17 +1812,17 @@ bool ValidateUseProgramStages(Context *c
 
 bool ValidateActiveShaderProgram(Context *context, GLuint pipeline, GLuint program)
 {
     UNIMPLEMENTED();
     return false;
 }
 
 bool ValidateCreateShaderProgramv(Context *context,
-                                  GLenum type,
+                                  ShaderType type,
                                   GLsizei count,
                                   const GLchar *const *strings)
 {
     UNIMPLEMENTED();
     return false;
 }
 
 bool ValidateGetProgramPipelineiv(Context *context, GLuint pipeline, GLenum pname, GLint *params)
--- a/gfx/angle/checkout/src/libANGLE/validationES31.h
+++ b/gfx/angle/checkout/src/libANGLE/validationES31.h
@@ -4,50 +4,71 @@
 // found in the LICENSE file.
 //
 
 // validationES31.h: Validation functions for OpenGL ES 3.1 entry point parameters
 
 #ifndef LIBANGLE_VALIDATION_ES31_H_
 #define LIBANGLE_VALIDATION_ES31_H_
 
+#include "libANGLE/PackedGLEnums.h"
+
 #include <GLES3/gl31.h>
 
 namespace gl
 {
 class Context;
-class ValidationContext;
 
 bool ValidateGetBooleani_v(Context *context, GLenum target, GLuint index, GLboolean *data);
 bool ValidateGetBooleani_vRobustANGLE(Context *context,
                                       GLenum target,
                                       GLuint index,
                                       GLsizei bufSize,
                                       GLsizei *length,
                                       GLboolean *data);
 
 bool ValidateGetTexLevelParameterfv(Context *context,
-                                    GLenum target,
+                                    TextureTarget target,
                                     GLint level,
                                     GLenum pname,
                                     GLfloat *params);
+bool ValidateGetTexLevelParameterfvRobustANGLE(Context *context,
+                                               TextureTarget target,
+                                               GLint level,
+                                               GLenum pname,
+                                               GLsizei bufSize,
+                                               GLsizei *length,
+                                               GLfloat *params);
 bool ValidateGetTexLevelParameteriv(Context *context,
-                                    GLenum target,
+                                    TextureTarget target,
                                     GLint level,
                                     GLenum pname,
                                     GLint *param);
+bool ValidateGetTexLevelParameterivRobustANGLE(Context *context,
+                                               TextureTarget target,
+                                               GLint level,
+                                               GLenum pname,
+                                               GLsizei bufSize,
+                                               GLsizei *length,
+                                               GLint *params);
 
 bool ValidateTexStorage2DMultisample(Context *context,
-                                     GLenum target,
+                                     TextureType target,
                                      GLsizei samples,
                                      GLint internalFormat,
                                      GLsizei width,
                                      GLsizei height,
                                      GLboolean fixedSampleLocations);
 bool ValidateGetMultisamplefv(Context *context, GLenum pname, GLuint index, GLfloat *val);
+bool ValidateGetMultisamplefvRobustANGLE(Context *context,
+                                         GLenum pname,
+                                         GLuint index,
+                                         GLsizei bufSize,
+                                         GLsizei *length,
+                                         GLfloat *val);
 
 bool ValidateDrawIndirectBase(Context *context, GLenum mode, const void *indirect);
 bool ValidateDrawArraysIndirect(Context *context, GLenum mode, const void *indirect);
 bool ValidateDrawElementsIndirect(Context *context, GLenum mode, GLenum type, const void *indirect);
 
 bool ValidateProgramUniform1i(Context *context, GLuint program, GLint location, GLint v0);
 bool ValidateProgramUniform2i(Context *context, GLuint program, GLint location, GLint v0, GLint v1);
 bool ValidateProgramUniform3i(Context *context,
@@ -223,16 +244,22 @@ bool ValidateProgramUniformMatrix4x3fv(C
                                        GLboolean transpose,
                                        const GLfloat *value);
 
 bool ValidateFramebufferParameteri(Context *context, GLenum target, GLenum pname, GLint param);
 bool ValidateGetFramebufferParameteriv(Context *context,
                                        GLenum target,
                                        GLenum pname,
                                        GLint *params);
+bool ValidateGetFramebufferParameterivRobustANGLE(Context *context,
+                                                  GLenum target,
+                                                  GLenum pname,
+                                                  GLsizei bufSize,
+                                                  GLsizei *length,
+                                                  GLint *params);
 
 bool ValidateGetProgramResourceIndex(Context *context,
                                      GLuint program,
                                      GLenum programInterface,
                                      const GLchar *name);
 bool ValidateGetProgramResourceName(Context *context,
                                     GLuint program,
                                     GLenum programInterface,
@@ -256,36 +283,41 @@ bool ValidateGetProgramResourceiv(Contex
                                   GLint *params);
 
 bool ValidateGetProgramInterfaceiv(Context *context,
                                    GLuint program,
                                    GLenum programInterface,
                                    GLenum pname,
                                    GLint *params);
 
-bool ValidateBindVertexBuffer(ValidationContext *context,
+bool ValidateGetProgramInterfaceivRobustANGLE(Context *context,
+                                              GLuint program,
+                                              GLenum programInterface,
+                                              GLenum pname,
+                                              GLsizei bufSize,
+                                              GLsizei *length,
+                                              GLint *params);
+bool ValidateBindVertexBuffer(Context *context,
                               GLuint bindingIndex,
                               GLuint buffer,
                               GLintptr offset,
                               GLsizei stride);
-bool ValidateVertexAttribFormat(ValidationContext *context,
+bool ValidateVertexAttribFormat(Context *context,
                                 GLuint attribindex,
                                 GLint size,
                                 GLenum type,
                                 GLboolean normalized,
                                 GLuint relativeoffset);
-bool ValidateVertexAttribIFormat(ValidationContext *context,
+bool ValidateVertexAttribIFormat(Context *context,
                                  GLuint attribindex,
                                  GLint size,
                                  GLenum type,
                                  GLuint relativeoffset);
-bool ValidateVertexAttribBinding(ValidationContext *context,
-                                 GLuint attribIndex,
-                                 GLuint bindingIndex);
-bool ValidateVertexBindingDivisor(ValidationContext *context, GLuint bindingIndex, GLuint divisor);
+bool ValidateVertexAttribBinding(Context *context, GLuint attribIndex, GLuint bindingIndex);
+bool ValidateVertexBindingDivisor(Context *context, GLuint bindingIndex, GLuint divisor);
 
 bool ValidateDispatchCompute(Context *context,
                              GLuint numGroupsX,
                              GLuint numGroupsY,
                              GLuint numGroupsZ);
 bool ValidateDispatchComputeIndirect(Context *context, GLintptr indirect);
 
 bool ValidateBindImageTexture(Context *context,
@@ -299,17 +331,17 @@ bool ValidateBindImageTexture(Context *c
 
 bool ValidateGenProgramPipelines(Context *context, GLint n, GLuint *pipelines);
 bool ValidateDeleteProgramPipelines(Context *context, GLint n, const GLuint *pipelines);
 bool ValidateBindProgramPipeline(Context *context, GLuint pipeline);
 bool ValidateIsProgramPipeline(Context *context, GLuint pipeline);
 bool ValidateUseProgramStages(Context *context, GLuint pipeline, GLbitfield stages, GLuint program);
 bool ValidateActiveShaderProgram(Context *context, GLuint pipeline, GLuint program);
 bool ValidateCreateShaderProgramv(Context *context,
-                                  GLenum type,
+                                  ShaderType type,
                                   GLsizei count,
                                   const GLchar *const *strings);
 bool ValidateGetProgramPipelineiv(Context *context, GLuint pipeline, GLenum pname, GLint *params);
 bool ValidateValidateProgramPipeline(Context *context, GLuint pipeline);
 bool ValidateGetProgramPipelineInfoLog(Context *context,
                                        GLuint pipeline,
                                        GLsizei bufSize,
                                        GLsizei *length,
--- a/gfx/angle/checkout/src/libGLESv2/entry_points_egl.cpp
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_egl.cpp
@@ -756,18 +756,19 @@ EGLBoolean EGLAPIENTRY BindTexImage(EGLD
     {
         thread->setError(EglBadMatch());
         return EGL_FALSE;
     }
 
     gl::Context *context = thread->getContext();
     if (context)
     {
-        GLenum target = egl_gl::EGLTextureTargetToGLTextureTarget(eglSurface->getTextureTarget());
-        gl::Texture *textureObject = context->getTargetTexture(target);
+        gl::TextureType type =
+            egl_gl::EGLTextureTargetToTextureType(eglSurface->getTextureTarget());
+        gl::Texture *textureObject = context->getTargetTexture(type);
         ASSERT(textureObject != nullptr);
 
         if (textureObject->getImmutableFormat())
         {
             thread->setError(EglBadMatch());
             return EGL_FALSE;
         }
 
--- a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_1_0_autogen.cpp
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_1_0_autogen.cpp
@@ -11,185 +11,46 @@
 #include "libGLESv2/entry_points_gles_1_0_autogen.h"
 
 #include "libANGLE/Context.h"
 #include "libANGLE/validationES1.h"
 #include "libGLESv2/global_state.h"
 
 namespace gl
 {
-void GL_APIENTRY ActiveTexture(GLenum texture)
-{
-    EVENT("(GLenum texture = 0x%X)", texture);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::ActiveTexture>(texture);
-
-        if (context->skipValidation() || ValidateActiveTexture(context, texture))
-        {
-            context->activeTexture(texture);
-        }
-    }
-}
-
 void GL_APIENTRY AlphaFunc(GLenum func, GLfloat ref)
 {
     EVENT("(GLenum func = 0x%X, GLfloat ref = %f)", func, ref);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::AlphaFunc>(func, ref);
+        AlphaTestFunc funcPacked = FromGLenum<AlphaTestFunc>(func);
+        context->gatherParams<EntryPoint::AlphaFunc>(funcPacked, ref);
 
-        if (context->skipValidation() || ValidateAlphaFunc(context, func, ref))
+        if (context->skipValidation() || ValidateAlphaFunc(context, funcPacked, ref))
         {
-            context->alphaFunc(func, ref);
+            context->alphaFunc(funcPacked, ref);
         }
     }
 }
 
 void GL_APIENTRY AlphaFuncx(GLenum func, GLfixed ref)
 {
     EVENT("(GLenum func = 0x%X, GLfixed ref = 0x%X)", func, ref);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::AlphaFuncx>(func, ref);
-
-        if (context->skipValidation() || ValidateAlphaFuncx(context, func, ref))
-        {
-            context->alphaFuncx(func, ref);
-        }
-    }
-}
-
-void GL_APIENTRY BindBuffer(GLenum target, GLuint buffer)
-{
-    EVENT("(GLenum target = 0x%X, GLuint buffer = %u)", target, buffer);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
-        context->gatherParams<EntryPoint::BindBuffer>(targetPacked, buffer);
-
-        if (context->skipValidation() || ValidateBindBuffer(context, targetPacked, buffer))
-        {
-            context->bindBuffer(targetPacked, buffer);
-        }
-    }
-}
-
-void GL_APIENTRY BindTexture(GLenum target, GLuint texture)
-{
-    EVENT("(GLenum target = 0x%X, GLuint texture = %u)", target, texture);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::BindTexture>(target, texture);
-
-        if (context->skipValidation() || ValidateBindTexture(context, target, texture))
-        {
-            context->bindTexture(target, texture);
-        }
-    }
-}
-
-void GL_APIENTRY BlendFunc(GLenum sfactor, GLenum dfactor)
-{
-    EVENT("(GLenum sfactor = 0x%X, GLenum dfactor = 0x%X)", sfactor, dfactor);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::BlendFunc>(sfactor, dfactor);
-
-        if (context->skipValidation() || ValidateBlendFunc(context, sfactor, dfactor))
-        {
-            context->blendFunc(sfactor, dfactor);
-        }
-    }
-}
-
-void GL_APIENTRY BufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
-{
-    EVENT(
-        "(GLenum target = 0x%X, GLsizeiptr size = %d, const void *data = 0x%0.8p, GLenum usage = "
-        "0x%X)",
-        target, size, data, usage);
+        AlphaTestFunc funcPacked = FromGLenum<AlphaTestFunc>(func);
+        context->gatherParams<EntryPoint::AlphaFuncx>(funcPacked, ref);
 
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
-        BufferUsage usagePacked    = FromGLenum<BufferUsage>(usage);
-        context->gatherParams<EntryPoint::BufferData>(targetPacked, size, data, usagePacked);
-
-        if (context->skipValidation() ||
-            ValidateBufferData(context, targetPacked, size, data, usagePacked))
-        {
-            context->bufferData(targetPacked, size, data, usagePacked);
-        }
-    }
-}
-
-void GL_APIENTRY BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
-{
-    EVENT(
-        "(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const void *data = "
-        "0x%0.8p)",
-        target, offset, size, data);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
-        context->gatherParams<EntryPoint::BufferSubData>(targetPacked, offset, size, data);
-
-        if (context->skipValidation() ||
-            ValidateBufferSubData(context, targetPacked, offset, size, data))
+        if (context->skipValidation() || ValidateAlphaFuncx(context, funcPacked, ref))
         {
-            context->bufferSubData(targetPacked, offset, size, data);
-        }
-    }
-}
-
-void GL_APIENTRY Clear(GLbitfield mask)
-{
-    EVENT("(GLbitfield mask = 0x%X)", mask);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::Clear>(mask);
-
-        if (context->skipValidation() || ValidateClear(context, mask))
-        {
-            context->clear(mask);
-        }
-    }
-}
-
-void GL_APIENTRY ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
-{
-    EVENT("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red,
-          green, blue, alpha);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::ClearColor>(red, green, blue, alpha);
-
-        if (context->skipValidation() || ValidateClearColor(context, red, green, blue, alpha))
-        {
-            context->clearColor(red, green, blue, alpha);
+            context->alphaFuncx(funcPacked, ref);
         }
     }
 }
 
 void GL_APIENTRY ClearColorx(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
 {
     EVENT("(GLfixed red = 0x%X, GLfixed green = 0x%X, GLfixed blue = 0x%X, GLfixed alpha = 0x%X)",
           red, green, blue, alpha);
@@ -201,64 +62,32 @@ void GL_APIENTRY ClearColorx(GLfixed red
 
         if (context->skipValidation() || ValidateClearColorx(context, red, green, blue, alpha))
         {
             context->clearColorx(red, green, blue, alpha);
         }
     }
 }
 
-void GL_APIENTRY ClearDepthf(GLfloat d)
-{
-    EVENT("(GLfloat d = %f)", d);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::ClearDepthf>(d);
-
-        if (context->skipValidation() || ValidateClearDepthf(context, d))
-        {
-            context->clearDepthf(d);
-        }
-    }
-}
-
 void GL_APIENTRY ClearDepthx(GLfixed depth)
 {
     EVENT("(GLfixed depth = 0x%X)", depth);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::ClearDepthx>(depth);
 
         if (context->skipValidation() || ValidateClearDepthx(context, depth))
         {
             context->clearDepthx(depth);
         }
     }
 }
 
-void GL_APIENTRY ClearStencil(GLint s)
-{
-    EVENT("(GLint s = %d)", s);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::ClearStencil>(s);
-
-        if (context->skipValidation() || ValidateClearStencil(context, s))
-        {
-            context->clearStencil(s);
-        }
-    }
-}
-
 void GL_APIENTRY ClientActiveTexture(GLenum texture)
 {
     EVENT("(GLenum texture = 0x%X)", texture);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::ClientActiveTexture>(texture);
@@ -348,33 +177,16 @@ void GL_APIENTRY Color4x(GLfixed red, GL
 
         if (context->skipValidation() || ValidateColor4x(context, red, green, blue, alpha))
         {
             context->color4x(red, green, blue, alpha);
         }
     }
 }
 
-void GL_APIENTRY ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
-{
-    EVENT("(GLboolean red = %u, GLboolean green = %u, GLboolean blue = %u, GLboolean alpha = %u)",
-          red, green, blue, alpha);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::ColorMask>(red, green, blue, alpha);
-
-        if (context->skipValidation() || ValidateColorMask(context, red, green, blue, alpha))
-        {
-            context->colorMask(red, green, blue, alpha);
-        }
-    }
-}
-
 void GL_APIENTRY ColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
 {
     EVENT(
         "(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const void *pointer = 0x%0.8p)",
         size, type, stride, pointer);
 
     Context *context = GetValidGlobalContext();
     if (context)
@@ -383,380 +195,64 @@ void GL_APIENTRY ColorPointer(GLint size
 
         if (context->skipValidation() || ValidateColorPointer(context, size, type, stride, pointer))
         {
             context->colorPointer(size, type, stride, pointer);
         }
     }
 }
 
-void GL_APIENTRY CompressedTexImage2D(GLenum target,
-                                      GLint level,
-                                      GLenum internalformat,
-                                      GLsizei width,
-                                      GLsizei height,
-                                      GLint border,
-                                      GLsizei imageSize,
-                                      const void *data)
-{
-    EVENT(
-        "(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = "
-        "%d, GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const void *data = "
-        "0x%0.8p)",
-        target, level, internalformat, width, height, border, imageSize, data);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::CompressedTexImage2D>(
-            target, level, internalformat, width, height, border, imageSize, data);
-
-        if (context->skipValidation() ||
-            ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
-                                         border, imageSize, data))
-        {
-            context->compressedTexImage2D(target, level, internalformat, width, height, border,
-                                          imageSize, data);
-        }
-    }
-}
-
-void GL_APIENTRY CompressedTexSubImage2D(GLenum target,
-                                         GLint level,
-                                         GLint xoffset,
-                                         GLint yoffset,
-                                         GLsizei width,
-                                         GLsizei height,
-                                         GLenum format,
-                                         GLsizei imageSize,
-                                         const void *data)
-{
-    EVENT(
-        "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, GLsizei "
-        "width = %d, GLsizei height = %d, GLenum format = 0x%X, GLsizei imageSize = %d, const void "
-        "*data = 0x%0.8p)",
-        target, level, xoffset, yoffset, width, height, format, imageSize, data);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::CompressedTexSubImage2D>(
-            target, level, xoffset, yoffset, width, height, format, imageSize, data);
-
-        if (context->skipValidation() ||
-            ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
-                                            format, imageSize, data))
-        {
-            context->compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format,
-                                             imageSize, data);
-        }
-    }
-}
-
-void GL_APIENTRY CopyTexImage2D(GLenum target,
-                                GLint level,
-                                GLenum internalformat,
-                                GLint x,
-                                GLint y,
-                                GLsizei width,
-                                GLsizei height,
-                                GLint border)
-{
-    EVENT(
-        "(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLint x = %d, "
-        "GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
-        target, level, internalformat, x, y, width, height, border);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::CopyTexImage2D>(target, level, internalformat, x, y,
-                                                          width, height, border);
-
-        if (context->skipValidation() ||
-            ValidateCopyTexImage2D(context, target, level, internalformat, x, y, width, height,
-                                   border))
-        {
-            context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
-        }
-    }
-}
-
-void GL_APIENTRY CopyTexSubImage2D(GLenum target,
-                                   GLint level,
-                                   GLint xoffset,
-                                   GLint yoffset,
-                                   GLint x,
-                                   GLint y,
-                                   GLsizei width,
-                                   GLsizei height)
-{
-    EVENT(
-        "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, GLint x "
-        "= %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
-        target, level, xoffset, yoffset, x, y, width, height);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::CopyTexSubImage2D>(target, level, xoffset, yoffset, x, y,
-                                                             width, height);
-
-        if (context->skipValidation() || ValidateCopyTexSubImage2D(context, target, level, xoffset,
-                                                                   yoffset, x, y, width, height))
-        {
-            context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
-        }
-    }
-}
-
-void GL_APIENTRY CullFace(GLenum mode)
-{
-    EVENT("(GLenum mode = 0x%X)", mode);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        CullFaceMode modePacked = FromGLenum<CullFaceMode>(mode);
-        context->gatherParams<EntryPoint::CullFace>(modePacked);
-
-        if (context->skipValidation() || ValidateCullFace(context, modePacked))
-        {
-            context->cullFace(modePacked);
-        }
-    }
-}
-
-void GL_APIENTRY DeleteBuffers(GLsizei n, const GLuint *buffers)
-{
-    EVENT("(GLsizei n = %d, const GLuint *buffers = 0x%0.8p)", n, buffers);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::DeleteBuffers>(n, buffers);
-
-        if (context->skipValidation() || ValidateDeleteBuffers(context, n, buffers))
-        {
-            context->deleteBuffers(n, buffers);
-        }
-    }
-}
-
-void GL_APIENTRY DeleteTextures(GLsizei n, const GLuint *textures)
-{
-    EVENT("(GLsizei n = %d, const GLuint *textures = 0x%0.8p)", n, textures);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::DeleteTextures>(n, textures);
-
-        if (context->skipValidation() || ValidateDeleteTextures(context, n, textures))
-        {
-            context->deleteTextures(n, textures);
-        }
-    }
-}
-
-void GL_APIENTRY DepthFunc(GLenum func)
-{
-    EVENT("(GLenum func = 0x%X)", func);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::DepthFunc>(func);
-
-        if (context->skipValidation() || ValidateDepthFunc(context, func))
-        {
-            context->depthFunc(func);
-        }
-    }
-}
-
-void GL_APIENTRY DepthMask(GLboolean flag)
-{
-    EVENT("(GLboolean flag = %u)", flag);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::DepthMask>(flag);
-
-        if (context->skipValidation() || ValidateDepthMask(context, flag))
-        {
-            context->depthMask(flag);
-        }
-    }
-}
-
-void GL_APIENTRY DepthRangef(GLfloat n, GLfloat f)
-{
-    EVENT("(GLfloat n = %f, GLfloat f = %f)", n, f);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::DepthRangef>(n, f);
-
-        if (context->skipValidation() || ValidateDepthRangef(context, n, f))
-        {
-            context->depthRangef(n, f);
-        }
-    }
-}
-
 void GL_APIENTRY DepthRangex(GLfixed n, GLfixed f)
 {
     EVENT("(GLfixed n = 0x%X, GLfixed f = 0x%X)", n, f);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::DepthRangex>(n, f);
 
         if (context->skipValidation() || ValidateDepthRangex(context, n, f))
         {
             context->depthRangex(n, f);
         }
     }
 }
 
-void GL_APIENTRY Disable(GLenum cap)
-{
-    EVENT("(GLenum cap = 0x%X)", cap);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::Disable>(cap);
-
-        if (context->skipValidation() || ValidateDisable(context, cap))
-        {
-            context->disable(cap);
-        }
-    }
-}
-
 void GL_APIENTRY DisableClientState(GLenum array)
 {
     EVENT("(GLenum array = 0x%X)", array);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::DisableClientState>(array);
 
         if (context->skipValidation() || ValidateDisableClientState(context, array))
         {
             context->disableClientState(array);
         }
     }
 }
 
-void GL_APIENTRY DrawArrays(GLenum mode, GLint first, GLsizei count)
-{
-    EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::DrawArrays>(mode, first, count);
-
-        if (context->skipValidation() || ValidateDrawArrays(context, mode, first, count))
-        {
-            context->drawArrays(mode, first, count);
-        }
-    }
-}
-
-void GL_APIENTRY DrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
-{
-    EVENT(
-        "(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = "
-        "0x%0.8p)",
-        mode, count, type, indices);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::DrawElements>(mode, count, type, indices);
-
-        if (context->skipValidation() || ValidateDrawElements(context, mode, count, type, indices))
-        {
-            context->drawElements(mode, count, type, indices);
-        }
-    }
-}
-
-void GL_APIENTRY Enable(GLenum cap)
-{
-    EVENT("(GLenum cap = 0x%X)", cap);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::Enable>(cap);
-
-        if (context->skipValidation() || ValidateEnable(context, cap))
-        {
-            context->enable(cap);
-        }
-    }
-}
-
 void GL_APIENTRY EnableClientState(GLenum array)
 {
     EVENT("(GLenum array = 0x%X)", array);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::EnableClientState>(array);
 
         if (context->skipValidation() || ValidateEnableClientState(context, array))
         {
             context->enableClientState(array);
         }
     }
 }
 
-void GL_APIENTRY Finish()
-{
-    EVENT("()");
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::Finish>();
-
-        if (context->skipValidation() || ValidateFinish(context))
-        {
-            context->finish();
-        }
-    }
-}
-
-void GL_APIENTRY Flush()
-{
-    EVENT("()");
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::Flush>();
-
-        if (context->skipValidation() || ValidateFlush(context))
-        {
-            context->flush();
-        }
-    }
-}
-
 void GL_APIENTRY Fogf(GLenum pname, GLfloat param)
 {
     EVENT("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::Fogf>(pname, param);
@@ -811,32 +307,16 @@ void GL_APIENTRY Fogxv(GLenum pname, con
 
         if (context->skipValidation() || ValidateFogxv(context, pname, param))
         {
             context->fogxv(pname, param);
         }
     }
 }
 
-void GL_APIENTRY FrontFace(GLenum mode)
-{
-    EVENT("(GLenum mode = 0x%X)", mode);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::FrontFace>(mode);
-
-        if (context->skipValidation() || ValidateFrontFace(context, mode))
-        {
-            context->frontFace(mode);
-        }
-    }
-}
-
 void GL_APIENTRY Frustumf(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f)
 {
     EVENT(
         "(GLfloat l = %f, GLfloat r = %f, GLfloat b = %f, GLfloat t = %f, GLfloat n = %f, GLfloat "
         "f = %f)",
         l, r, b, t, n, f);
 
     Context *context = GetValidGlobalContext();
@@ -865,83 +345,16 @@ void GL_APIENTRY Frustumx(GLfixed l, GLf
 
         if (context->skipValidation() || ValidateFrustumx(context, l, r, b, t, n, f))
         {
             context->frustumx(l, r, b, t, n, f);
         }
     }
 }
 
-void GL_APIENTRY GenBuffers(GLsizei n, GLuint *buffers)
-{
-    EVENT("(GLsizei n = %d, GLuint *buffers = 0x%0.8p)", n, buffers);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GenBuffers>(n, buffers);
-
-        if (context->skipValidation() || ValidateGenBuffers(context, n, buffers))
-        {
-            context->genBuffers(n, buffers);
-        }
-    }
-}
-
-void GL_APIENTRY GenTextures(GLsizei n, GLuint *textures)
-{
-    EVENT("(GLsizei n = %d, GLuint *textures = 0x%0.8p)", n, textures);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GenTextures>(n, textures);
-
-        if (context->skipValidation() || ValidateGenTextures(context, n, textures))
-        {
-            context->genTextures(n, textures);
-        }
-    }
-}
-
-void GL_APIENTRY GetBooleanv(GLenum pname, GLboolean *data)
-{
-    EVENT("(GLenum pname = 0x%X, GLboolean *data = 0x%0.8p)", pname, data);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetBooleanv>(pname, data);
-
-        if (context->skipValidation() || ValidateGetBooleanv(context, pname, data))
-        {
-            context->getBooleanv(pname, data);
-        }
-    }
-}
-
-void GL_APIENTRY GetBufferParameteriv(GLenum target, GLenum pname, GLint *params)
-{
-    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname,
-          params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
-        context->gatherParams<EntryPoint::GetBufferParameteriv>(targetPacked, pname, params);
-
-        if (context->skipValidation() ||
-            ValidateGetBufferParameteriv(context, targetPacked, pname, params))
-        {
-            context->getBufferParameteriv(targetPacked, pname, params);
-        }
-    }
-}
-
 void GL_APIENTRY GetClipPlanef(GLenum plane, GLfloat *equation)
 {
     EVENT("(GLenum plane = 0x%X, GLfloat *equation = 0x%0.8p)", plane, equation);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::GetClipPlanef>(plane, equation);
@@ -964,82 +377,32 @@ void GL_APIENTRY GetClipPlanex(GLenum pl
 
         if (context->skipValidation() || ValidateGetClipPlanex(context, plane, equation))
         {
             context->getClipPlanex(plane, equation);
         }
     }
 }
 
-GLenum GL_APIENTRY GetError()
-{
-    EVENT("()");
-
-    Context *context = GetGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetError>();
-
-        if (context->skipValidation() || ValidateGetError(context))
-        {
-            return context->getError();
-        }
-    }
-
-    return GetDefaultReturnValue<EntryPoint::GetError, GLenum>();
-}
-
 void GL_APIENTRY GetFixedv(GLenum pname, GLfixed *params)
 {
     EVENT("(GLenum pname = 0x%X, GLfixed *params = 0x%0.8p)", pname, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::GetFixedv>(pname, params);
 
         if (context->skipValidation() || ValidateGetFixedv(context, pname, params))
         {
             context->getFixedv(pname, params);
         }
     }
 }
 
-void GL_APIENTRY GetFloatv(GLenum pname, GLfloat *data)
-{
-    EVENT("(GLenum pname = 0x%X, GLfloat *data = 0x%0.8p)", pname, data);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetFloatv>(pname, data);
-
-        if (context->skipValidation() || ValidateGetFloatv(context, pname, data))
-        {
-            context->getFloatv(pname, data);
-        }
-    }
-}
-
-void GL_APIENTRY GetIntegerv(GLenum pname, GLint *data)
-{
-    EVENT("(GLenum pname = 0x%X, GLint *data = 0x%0.8p)", pname, data);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetIntegerv>(pname, data);
-
-        if (context->skipValidation() || ValidateGetIntegerv(context, pname, data))
-        {
-            context->getIntegerv(pname, data);
-        }
-    }
-}
-
 void GL_APIENTRY GetLightfv(GLenum light, GLenum pname, GLfloat *params)
 {
     EVENT("(GLenum light = 0x%X, GLenum pname = 0x%X, GLfloat *params = 0x%0.8p)", light, pname,
           params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
@@ -1114,34 +477,16 @@ void GL_APIENTRY GetPointerv(GLenum pnam
 
         if (context->skipValidation() || ValidateGetPointerv(context, pname, params))
         {
             context->getPointerv(pname, params);
         }
     }
 }
 
-const GLubyte *GL_APIENTRY GetString(GLenum name)
-{
-    EVENT("(GLenum name = 0x%X)", name);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetString>(name);
-
-        if (context->skipValidation() || ValidateGetString(context, name))
-        {
-            return context->getString(name);
-        }
-    }
-
-    return GetDefaultReturnValue<EntryPoint::GetString, const GLubyte *>();
-}
-
 void GL_APIENTRY GetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
 {
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat *params = 0x%0.8p)", target, pname,
           params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
@@ -1183,135 +528,33 @@ void GL_APIENTRY GetTexEnvxv(GLenum targ
 
         if (context->skipValidation() || ValidateGetTexEnvxv(context, target, pname, params))
         {
             context->getTexEnvxv(target, pname, params);
         }
     }
 }
 
-void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
-{
-    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat *params = 0x%0.8p)", target, pname,
-          params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetTexParameterfv>(target, pname, params);
-
-        if (context->skipValidation() || ValidateGetTexParameterfv(context, target, pname, params))
-        {
-            context->getTexParameterfv(target, pname, params);
-        }
-    }
-}
-
-void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint *params)
-{
-    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname,
-          params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetTexParameteriv>(target, pname, params);
-
-        if (context->skipValidation() || ValidateGetTexParameteriv(context, target, pname, params))
-        {
-            context->getTexParameteriv(target, pname, params);
-        }
-    }
-}
-
 void GL_APIENTRY GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
 {
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfixed *params = 0x%0.8p)", target, pname,
           params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::GetTexParameterxv>(target, pname, params);
-
-        if (context->skipValidation() || ValidateGetTexParameterxv(context, target, pname, params))
-        {
-            context->getTexParameterxv(target, pname, params);
-        }
-    }
-}
-
-void GL_APIENTRY Hint(GLenum target, GLenum mode)
-{
-    EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::Hint>(target, mode);
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::GetTexParameterxv>(targetPacked, pname, params);
 
-        if (context->skipValidation() || ValidateHint(context, target, mode))
+        if (context->skipValidation() ||
+            ValidateGetTexParameterxv(context, targetPacked, pname, params))
         {
-            context->hint(target, mode);
-        }
-    }
-}
-
-GLboolean GL_APIENTRY IsBuffer(GLuint buffer)
-{
-    EVENT("(GLuint buffer = %u)", buffer);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::IsBuffer>(buffer);
-
-        if (context->skipValidation() || ValidateIsBuffer(context, buffer))
-        {
-            return context->isBuffer(buffer);
+            context->getTexParameterxv(targetPacked, pname, params);
         }
     }
-
-    return GetDefaultReturnValue<EntryPoint::IsBuffer, GLboolean>();
-}
-
-GLboolean GL_APIENTRY IsEnabled(GLenum cap)
-{
-    EVENT("(GLenum cap = 0x%X)", cap);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::IsEnabled>(cap);
-
-        if (context->skipValidation() || ValidateIsEnabled(context, cap))
-        {
-            return context->isEnabled(cap);
-        }
-    }
-
-    return GetDefaultReturnValue<EntryPoint::IsEnabled, GLboolean>();
-}
-
-GLboolean GL_APIENTRY IsTexture(GLuint texture)
-{
-    EVENT("(GLuint texture = %u)", texture);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::IsTexture>(texture);
-
-        if (context->skipValidation() || ValidateIsTexture(context, texture))
-        {
-            return context->isTexture(texture);
-        }
-    }
-
-    return GetDefaultReturnValue<EntryPoint::IsTexture, GLboolean>();
 }
 
 void GL_APIENTRY LightModelf(GLenum pname, GLfloat param)
 {
     EVENT("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
 
     Context *context = GetValidGlobalContext();
     if (context)
@@ -1434,32 +677,16 @@ void GL_APIENTRY Lightxv(GLenum light, G
 
         if (context->skipValidation() || ValidateLightxv(context, light, pname, params))
         {
             context->lightxv(light, pname, params);
         }
     }
 }
 
-void GL_APIENTRY LineWidth(GLfloat width)
-{
-    EVENT("(GLfloat width = %f)", width);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::LineWidth>(width);
-
-        if (context->skipValidation() || ValidateLineWidth(context, width))
-        {
-            context->lineWidth(width);
-        }
-    }
-}
-
 void GL_APIENTRY LineWidthx(GLfixed width)
 {
     EVENT("(GLfixed width = 0x%X)", width);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::LineWidthx>(width);
@@ -1603,21 +830,22 @@ void GL_APIENTRY Materialxv(GLenum face,
 
 void GL_APIENTRY MatrixMode(GLenum mode)
 {
     EVENT("(GLenum mode = 0x%X)", mode);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::MatrixMode>(mode);
+        MatrixType modePacked = FromGLenum<MatrixType>(mode);
+        context->gatherParams<EntryPoint::MatrixMode>(modePacked);
 
-        if (context->skipValidation() || ValidateMatrixMode(context, mode))
+        if (context->skipValidation() || ValidateMatrixMode(context, modePacked))
         {
-            context->matrixMode(mode);
+            context->matrixMode(modePacked);
         }
     }
 }
 
 void GL_APIENTRY MultMatrixf(const GLfloat *m)
 {
     EVENT("(const GLfloat *m = 0x%0.8p)", m);
 
@@ -1767,32 +995,16 @@ void GL_APIENTRY Orthox(GLfixed l, GLfix
 
         if (context->skipValidation() || ValidateOrthox(context, l, r, b, t, n, f))
         {
             context->orthox(l, r, b, t, n, f);
         }
     }
 }
 
-void GL_APIENTRY PixelStorei(GLenum pname, GLint param)
-{
-    EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::PixelStorei>(pname, param);
-
-        if (context->skipValidation() || ValidatePixelStorei(context, pname, param))
-        {
-            context->pixelStorei(pname, param);
-        }
-    }
-}
-
 void GL_APIENTRY PointParameterf(GLenum pname, GLfloat param)
 {
     EVENT("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::PointParameterf>(pname, param);
@@ -1879,32 +1091,16 @@ void GL_APIENTRY PointSizex(GLfixed size
 
         if (context->skipValidation() || ValidatePointSizex(context, size))
         {
             context->pointSizex(size);
         }
     }
 }
 
-void GL_APIENTRY PolygonOffset(GLfloat factor, GLfloat units)
-{
-    EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::PolygonOffset>(factor, units);
-
-        if (context->skipValidation() || ValidatePolygonOffset(context, factor, units))
-        {
-            context->polygonOffset(factor, units);
-        }
-    }
-}
-
 void GL_APIENTRY PolygonOffsetx(GLfixed factor, GLfixed units)
 {
     EVENT("(GLfixed factor = 0x%X, GLfixed units = 0x%X)", factor, units);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::PolygonOffsetx>(factor, units);
@@ -1943,42 +1139,16 @@ void GL_APIENTRY PushMatrix()
 
         if (context->skipValidation() || ValidatePushMatrix(context))
         {
             context->pushMatrix();
         }
     }
 }
 
-void GL_APIENTRY ReadPixels(GLint x,
-                            GLint y,
-                            GLsizei width,
-                            GLsizei height,
-                            GLenum format,
-                            GLenum type,
-                            void *pixels)
-{
-    EVENT(
-        "(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLenum format = "
-        "0x%X, GLenum type = 0x%X, void *pixels = 0x%0.8p)",
-        x, y, width, height, format, type, pixels);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::ReadPixels>(x, y, width, height, format, type, pixels);
-
-        if (context->skipValidation() ||
-            ValidateReadPixels(context, x, y, width, height, format, type, pixels))
-        {
-            context->readPixels(x, y, width, height, format, type, pixels);
-        }
-    }
-}
-
 void GL_APIENTRY Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
 {
     EVENT("(GLfloat angle = %f, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", angle, x, y, z);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::Rotatef>(angle, x, y, z);
@@ -2002,32 +1172,16 @@ void GL_APIENTRY Rotatex(GLfixed angle, 
 
         if (context->skipValidation() || ValidateRotatex(context, angle, x, y, z))
         {
             context->rotatex(angle, x, y, z);
         }
     }
 }
 
-void GL_APIENTRY SampleCoverage(GLfloat value, GLboolean invert)
-{
-    EVENT("(GLfloat value = %f, GLboolean invert = %u)", value, invert);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::SampleCoverage>(value, invert);
-
-        if (context->skipValidation() || ValidateSampleCoverage(context, value, invert))
-        {
-            context->sampleCoverage(value, invert);
-        }
-    }
-}
-
 void GL_APIENTRY SampleCoveragex(GLclampx value, GLboolean invert)
 {
     EVENT("(GLclampx value = 0x%X, GLboolean invert = %u)", value, invert);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::SampleCoveragex>(value, invert);
@@ -2066,97 +1220,32 @@ void GL_APIENTRY Scalex(GLfixed x, GLfix
 
         if (context->skipValidation() || ValidateScalex(context, x, y, z))
         {
             context->scalex(x, y, z);
         }
     }
 }
 
-void GL_APIENTRY Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
-{
-    EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width,
-          height);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::Scissor>(x, y, width, height);
-
-        if (context->skipValidation() || ValidateScissor(context, x, y, width, height))
-        {
-            context->scissor(x, y, width, height);
-        }
-    }
-}
-
 void GL_APIENTRY ShadeModel(GLenum mode)
 {
     EVENT("(GLenum mode = 0x%X)", mode);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::ShadeModel>(mode);
 
         if (context->skipValidation() || ValidateShadeModel(context, mode))
         {
             context->shadeModel(mode);
         }
     }
 }
 
-void GL_APIENTRY StencilFunc(GLenum func, GLint ref, GLuint mask)
-{
-    EVENT("(GLenum func = 0x%X, GLint ref = %d, GLuint mask = %u)", func, ref, mask);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::StencilFunc>(func, ref, mask);
-
-        if (context->skipValidation() || ValidateStencilFunc(context, func, ref, mask))
-        {
-            context->stencilFunc(func, ref, mask);
-        }
-    }
-}
-
-void GL_APIENTRY StencilMask(GLuint mask)
-{
-    EVENT("(GLuint mask = %u)", mask);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::StencilMask>(mask);
-
-        if (context->skipValidation() || ValidateStencilMask(context, mask))
-        {
-            context->stencilMask(mask);
-        }
-    }
-}
-
-void GL_APIENTRY StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
-{
-    EVENT("(GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpass = 0x%X)", fail, zfail, zpass);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::StencilOp>(fail, zfail, zpass);
-
-        if (context->skipValidation() || ValidateStencilOp(context, fail, zfail, zpass))
-        {
-            context->stencilOp(fail, zfail, zpass);
-        }
-    }
-}
-
 void GL_APIENTRY TexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
 {
     EVENT(
         "(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const void *pointer = 0x%0.8p)",
         size, type, stride, pointer);
 
     Context *context = GetValidGlobalContext();
     if (context)
@@ -2266,176 +1355,49 @@ void GL_APIENTRY TexEnvxv(GLenum target,
 
         if (context->skipValidation() || ValidateTexEnvxv(context, target, pname, params))
         {
             context->texEnvxv(target, pname, params);
         }
     }
 }
 
-void GL_APIENTRY TexImage2D(GLenum target,
-                            GLint level,
-                            GLint internalformat,
-                            GLsizei width,
-                            GLsizei height,
-                            GLint border,
-                            GLenum format,
-                            GLenum type,
-                            const void *pixels)
-{
-    EVENT(
-        "(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, "
-        "GLsizei height = %d, GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const "
-        "void *pixels = 0x%0.8p)",
-        target, level, internalformat, width, height, border, format, type, pixels);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::TexImage2D>(target, level, internalformat, width, height,
-                                                      border, format, type, pixels);
-
-        if (context->skipValidation() ||
-            ValidateTexImage2D(context, target, level, internalformat, width, height, border,
-                               format, type, pixels))
-        {
-            context->texImage2D(target, level, internalformat, width, height, border, format, type,
-                                pixels);
-        }
-    }
-}
-
-void GL_APIENTRY TexParameterf(GLenum target, GLenum pname, GLfloat param)
-{
-    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::TexParameterf>(target, pname, param);
-
-        if (context->skipValidation() || ValidateTexParameterf(context, target, pname, param))
-        {
-            context->texParameterf(target, pname, param);
-        }
-    }
-}
-
-void GL_APIENTRY TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
-{
-    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLfloat *params = 0x%0.8p)", target,
-          pname, params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::TexParameterfv>(target, pname, params);
-
-        if (context->skipValidation() || ValidateTexParameterfv(context, target, pname, params))
-        {
-            context->texParameterfv(target, pname, params);
-        }
-    }
-}
-
-void GL_APIENTRY TexParameteri(GLenum target, GLenum pname, GLint param)
-{
-    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::TexParameteri>(target, pname, param);
-
-        if (context->skipValidation() || ValidateTexParameteri(context, target, pname, param))
-        {
-            context->texParameteri(target, pname, param);
-        }
-    }
-}
-
-void GL_APIENTRY TexParameteriv(GLenum target, GLenum pname, const GLint *params)
-{
-    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLint *params = 0x%0.8p)", target,
-          pname, params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::TexParameteriv>(target, pname, params);
-
-        if (context->skipValidation() || ValidateTexParameteriv(context, target, pname, params))
-        {
-            context->texParameteriv(target, pname, params);
-        }
-    }
-}
-
 void GL_APIENTRY TexParameterx(GLenum target, GLenum pname, GLfixed param)
 {
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfixed param = 0x%X)", target, pname,
           param);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::TexParameterx>(target, pname, param);
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::TexParameterx>(targetPacked, pname, param);
 
-        if (context->skipValidation() || ValidateTexParameterx(context, target, pname, param))
+        if (context->skipValidation() || ValidateTexParameterx(context, targetPacked, pname, param))
         {
-            context->texParameterx(target, pname, param);
+            context->texParameterx(targetPacked, pname, param);
         }
     }
 }
 
 void GL_APIENTRY TexParameterxv(GLenum target, GLenum pname, const GLfixed *params)
 {
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLfixed *params = 0x%0.8p)", target,
           pname, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::TexParameterxv>(target, pname, params);
-
-        if (context->skipValidation() || ValidateTexParameterxv(context, target, pname, params))
-        {
-            context->texParameterxv(target, pname, params);
-        }
-    }
-}
-
-void GL_APIENTRY TexSubImage2D(GLenum target,
-                               GLint level,
-                               GLint xoffset,
-                               GLint yoffset,
-                               GLsizei width,
-                               GLsizei height,
-                               GLenum format,
-                               GLenum type,
-                               const void *pixels)
-{
-    EVENT(
-        "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, GLsizei "
-        "width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, const void "
-        "*pixels = 0x%0.8p)",
-        target, level, xoffset, yoffset, width, height, format, type, pixels);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::TexSubImage2D>(target, level, xoffset, yoffset, width,
-                                                         height, format, type, pixels);
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::TexParameterxv>(targetPacked, pname, params);
 
         if (context->skipValidation() ||
-            ValidateTexSubImage2D(context, target, level, xoffset, yoffset, width, height, format,
-                                  type, pixels))
+            ValidateTexParameterxv(context, targetPacked, pname, params))
         {
-            context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type,
-                                   pixels);
+            context->texParameterxv(targetPacked, pname, params);
         }
     }
 }
 
 void GL_APIENTRY Translatef(GLfloat x, GLfloat y, GLfloat z)
 {
     EVENT("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
 
@@ -2480,26 +1442,9 @@ void GL_APIENTRY VertexPointer(GLint siz
 
         if (context->skipValidation() ||
             ValidateVertexPointer(context, size, type, stride, pointer))
         {
             context->vertexPointer(size, type, stride, pointer);
         }
     }
 }
-
-void GL_APIENTRY Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
-{
-    EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width,
-          height);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::Viewport>(x, y, width, height);
-
-        if (context->skipValidation() || ValidateViewport(context, x, y, width, height))
-        {
-            context->viewport(x, y, width, height);
-        }
-    }
-}
 }  // namespace gl
--- a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_1_0_autogen.h
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_1_0_autogen.h
@@ -11,145 +11,61 @@
 #ifndef LIBGLESV2_ENTRY_POINTS_GLES_1_0_AUTOGEN_H_
 #define LIBGLESV2_ENTRY_POINTS_GLES_1_0_AUTOGEN_H_
 
 #include <GLES/gl.h>
 #include <export.h>
 
 namespace gl
 {
-ANGLE_EXPORT void GL_APIENTRY ActiveTexture(GLenum texture);
 ANGLE_EXPORT void GL_APIENTRY AlphaFunc(GLenum func, GLfloat ref);
 ANGLE_EXPORT void GL_APIENTRY AlphaFuncx(GLenum func, GLfixed ref);
-ANGLE_EXPORT void GL_APIENTRY BindBuffer(GLenum target, GLuint buffer);
-ANGLE_EXPORT void GL_APIENTRY BindTexture(GLenum target, GLuint texture);
-ANGLE_EXPORT void GL_APIENTRY BlendFunc(GLenum sfactor, GLenum dfactor);
-ANGLE_EXPORT void GL_APIENTRY BufferData(GLenum target,
-                                         GLsizeiptr size,
-                                         const void *data,
-                                         GLenum usage);
-ANGLE_EXPORT void GL_APIENTRY BufferSubData(GLenum target,
-                                            GLintptr offset,
-                                            GLsizeiptr size,
-                                            const void *data);
-ANGLE_EXPORT void GL_APIENTRY Clear(GLbitfield mask);
-ANGLE_EXPORT void GL_APIENTRY ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
 ANGLE_EXPORT void GL_APIENTRY ClearColorx(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
-ANGLE_EXPORT void GL_APIENTRY ClearDepthf(GLfloat d);
 ANGLE_EXPORT void GL_APIENTRY ClearDepthx(GLfixed depth);
-ANGLE_EXPORT void GL_APIENTRY ClearStencil(GLint s);
 ANGLE_EXPORT void GL_APIENTRY ClientActiveTexture(GLenum texture);
 ANGLE_EXPORT void GL_APIENTRY ClipPlanef(GLenum p, const GLfloat *eqn);
 ANGLE_EXPORT void GL_APIENTRY ClipPlanex(GLenum plane, const GLfixed *equation);
 ANGLE_EXPORT void GL_APIENTRY Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
 ANGLE_EXPORT void GL_APIENTRY Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
 ANGLE_EXPORT void GL_APIENTRY Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
-ANGLE_EXPORT void GL_APIENTRY ColorMask(GLboolean red,
-                                        GLboolean green,
-                                        GLboolean blue,
-                                        GLboolean alpha);
 ANGLE_EXPORT void GL_APIENTRY ColorPointer(GLint size,
                                            GLenum type,
                                            GLsizei stride,
                                            const void *pointer);
-ANGLE_EXPORT void GL_APIENTRY CompressedTexImage2D(GLenum target,
-                                                   GLint level,
-                                                   GLenum internalformat,
-                                                   GLsizei width,
-                                                   GLsizei height,
-                                                   GLint border,
-                                                   GLsizei imageSize,
-                                                   const void *data);
-ANGLE_EXPORT void GL_APIENTRY CompressedTexSubImage2D(GLenum target,
-                                                      GLint level,
-                                                      GLint xoffset,
-                                                      GLint yoffset,
-                                                      GLsizei width,
-                                                      GLsizei height,
-                                                      GLenum format,
-                                                      GLsizei imageSize,
-                                                      const void *data);
-ANGLE_EXPORT void GL_APIENTRY CopyTexImage2D(GLenum target,
-                                             GLint level,
-                                             GLenum internalformat,
-                                             GLint x,
-                                             GLint y,
-                                             GLsizei width,
-                                             GLsizei height,
-                                             GLint border);
-ANGLE_EXPORT void GL_APIENTRY CopyTexSubImage2D(GLenum target,
-                                                GLint level,
-                                                GLint xoffset,
-                                                GLint yoffset,
-                                                GLint x,
-                                                GLint y,
-                                                GLsizei width,
-                                                GLsizei height);
-ANGLE_EXPORT void GL_APIENTRY CullFace(GLenum mode);
-ANGLE_EXPORT void GL_APIENTRY DeleteBuffers(GLsizei n, const GLuint *buffers);
-ANGLE_EXPORT void GL_APIENTRY DeleteTextures(GLsizei n, const GLuint *textures);
-ANGLE_EXPORT void GL_APIENTRY DepthFunc(GLenum func);
-ANGLE_EXPORT void GL_APIENTRY DepthMask(GLboolean flag);
-ANGLE_EXPORT void GL_APIENTRY DepthRangef(GLfloat n, GLfloat f);
 ANGLE_EXPORT void GL_APIENTRY DepthRangex(GLfixed n, GLfixed f);
-ANGLE_EXPORT void GL_APIENTRY Disable(GLenum cap);
 ANGLE_EXPORT void GL_APIENTRY DisableClientState(GLenum array);
-ANGLE_EXPORT void GL_APIENTRY DrawArrays(GLenum mode, GLint first, GLsizei count);
-ANGLE_EXPORT void GL_APIENTRY DrawElements(GLenum mode,
-                                           GLsizei count,
-                                           GLenum type,
-                                           const void *indices);
-ANGLE_EXPORT void GL_APIENTRY Enable(GLenum cap);
 ANGLE_EXPORT void GL_APIENTRY EnableClientState(GLenum array);
-ANGLE_EXPORT void GL_APIENTRY Finish();
-ANGLE_EXPORT void GL_APIENTRY Flush();
 ANGLE_EXPORT void GL_APIENTRY Fogf(GLenum pname, GLfloat param);
 ANGLE_EXPORT void GL_APIENTRY Fogfv(GLenum pname, const GLfloat *params);
 ANGLE_EXPORT void GL_APIENTRY Fogx(GLenum pname, GLfixed param);
 ANGLE_EXPORT void GL_APIENTRY Fogxv(GLenum pname, const GLfixed *param);
-ANGLE_EXPORT void GL_APIENTRY FrontFace(GLenum mode);
 ANGLE_EXPORT void GL_APIENTRY
 Frustumf(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);
 ANGLE_EXPORT void GL_APIENTRY
 Frustumx(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f);
-ANGLE_EXPORT void GL_APIENTRY GenBuffers(GLsizei n, GLuint *buffers);
-ANGLE_EXPORT void GL_APIENTRY GenTextures(GLsizei n, GLuint *textures);
-ANGLE_EXPORT void GL_APIENTRY GetBooleanv(GLenum pname, GLboolean *data);
-ANGLE_EXPORT void GL_APIENTRY GetBufferParameteriv(GLenum target, GLenum pname, GLint *params);
 ANGLE_EXPORT void GL_APIENTRY GetClipPlanef(GLenum plane, GLfloat *equation);
 ANGLE_EXPORT void GL_APIENTRY GetClipPlanex(GLenum plane, GLfixed *equation);
-ANGLE_EXPORT GLenum GL_APIENTRY GetError();
 ANGLE_EXPORT void GL_APIENTRY GetFixedv(GLenum pname, GLfixed *params);
-ANGLE_EXPORT void GL_APIENTRY GetFloatv(GLenum pname, GLfloat *data);
-ANGLE_EXPORT void GL_APIENTRY GetIntegerv(GLenum pname, GLint *data);
 ANGLE_EXPORT void GL_APIENTRY GetLightfv(GLenum light, GLenum pname, GLfloat *params);
 ANGLE_EXPORT void GL_APIENTRY GetLightxv(GLenum light, GLenum pname, GLfixed *params);
 ANGLE_EXPORT void GL_APIENTRY GetMaterialfv(GLenum face, GLenum pname, GLfloat *params);
 ANGLE_EXPORT void GL_APIENTRY GetMaterialxv(GLenum face, GLenum pname, GLfixed *params);
 ANGLE_EXPORT void GL_APIENTRY GetPointerv(GLenum pname, void **params);
-ANGLE_EXPORT const GLubyte *GL_APIENTRY GetString(GLenum name);
 ANGLE_EXPORT void GL_APIENTRY GetTexEnvfv(GLenum target, GLenum pname, GLfloat *params);
 ANGLE_EXPORT void GL_APIENTRY GetTexEnviv(GLenum target, GLenum pname, GLint *params);
 ANGLE_EXPORT void GL_APIENTRY GetTexEnvxv(GLenum target, GLenum pname, GLfixed *params);
-ANGLE_EXPORT void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params);
-ANGLE_EXPORT void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint *params);
 ANGLE_EXPORT void GL_APIENTRY GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params);
-ANGLE_EXPORT void GL_APIENTRY Hint(GLenum target, GLenum mode);
-ANGLE_EXPORT GLboolean GL_APIENTRY IsBuffer(GLuint buffer);
-ANGLE_EXPORT GLboolean GL_APIENTRY IsEnabled(GLenum cap);
-ANGLE_EXPORT GLboolean GL_APIENTRY IsTexture(GLuint texture);
 ANGLE_EXPORT void GL_APIENTRY LightModelf(GLenum pname, GLfloat param);
 ANGLE_EXPORT void GL_APIENTRY LightModelfv(GLenum pname, const GLfloat *params);
 ANGLE_EXPORT void GL_APIENTRY LightModelx(GLenum pname, GLfixed param);
 ANGLE_EXPORT void GL_APIENTRY LightModelxv(GLenum pname, const GLfixed *param);
 ANGLE_EXPORT void GL_APIENTRY Lightf(GLenum light, GLenum pname, GLfloat param);
 ANGLE_EXPORT void GL_APIENTRY Lightfv(GLenum light, GLenum pname, const GLfloat *params);
 ANGLE_EXPORT void GL_APIENTRY Lightx(GLenum light, GLenum pname, GLfixed param);
 ANGLE_EXPORT void GL_APIENTRY Lightxv(GLenum light, GLenum pname, const GLfixed *params);
-ANGLE_EXPORT void GL_APIENTRY LineWidth(GLfloat width);
 ANGLE_EXPORT void GL_APIENTRY LineWidthx(GLfixed width);
 ANGLE_EXPORT void GL_APIENTRY LoadIdentity();
 ANGLE_EXPORT void GL_APIENTRY LoadMatrixf(const GLfloat *m);
 ANGLE_EXPORT void GL_APIENTRY LoadMatrixx(const GLfixed *m);
 ANGLE_EXPORT void GL_APIENTRY LogicOp(GLenum opcode);
 ANGLE_EXPORT void GL_APIENTRY Materialf(GLenum face, GLenum pname, GLfloat param);
 ANGLE_EXPORT void GL_APIENTRY Materialfv(GLenum face, GLenum pname, const GLfloat *params);
 ANGLE_EXPORT void GL_APIENTRY Materialx(GLenum face, GLenum pname, GLfixed param);
@@ -163,81 +79,44 @@ ANGLE_EXPORT void GL_APIENTRY
 MultiTexCoord4x(GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
 ANGLE_EXPORT void GL_APIENTRY Normal3f(GLfloat nx, GLfloat ny, GLfloat nz);
 ANGLE_EXPORT void GL_APIENTRY Normal3x(GLfixed nx, GLfixed ny, GLfixed nz);
 ANGLE_EXPORT void GL_APIENTRY NormalPointer(GLenum type, GLsizei stride, const void *pointer);
 ANGLE_EXPORT void GL_APIENTRY
 Orthof(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);
 ANGLE_EXPORT void GL_APIENTRY
 Orthox(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f);
-ANGLE_EXPORT void GL_APIENTRY PixelStorei(GLenum pname, GLint param);
 ANGLE_EXPORT void GL_APIENTRY PointParameterf(GLenum pname, GLfloat param);
 ANGLE_EXPORT void GL_APIENTRY PointParameterfv(GLenum pname, const GLfloat *params);
 ANGLE_EXPORT void GL_APIENTRY PointParameterx(GLenum pname, GLfixed param);
 ANGLE_EXPORT void GL_APIENTRY PointParameterxv(GLenum pname, const GLfixed *params);
 ANGLE_EXPORT void GL_APIENTRY PointSize(GLfloat size);
 ANGLE_EXPORT void GL_APIENTRY PointSizex(GLfixed size);
-ANGLE_EXPORT void GL_APIENTRY PolygonOffset(GLfloat factor, GLfloat units);
 ANGLE_EXPORT void GL_APIENTRY PolygonOffsetx(GLfixed factor, GLfixed units);
 ANGLE_EXPORT void GL_APIENTRY PopMatrix();
 ANGLE_EXPORT void GL_APIENTRY PushMatrix();
-ANGLE_EXPORT void GL_APIENTRY ReadPixels(GLint x,
-                                         GLint y,
-                                         GLsizei width,
-                                         GLsizei height,
-                                         GLenum format,
-                                         GLenum type,
-                                         void *pixels);
 ANGLE_EXPORT void GL_APIENTRY Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
 ANGLE_EXPORT void GL_APIENTRY Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
-ANGLE_EXPORT void GL_APIENTRY SampleCoverage(GLfloat value, GLboolean invert);
 ANGLE_EXPORT void GL_APIENTRY SampleCoveragex(GLclampx value, GLboolean invert);
 ANGLE_EXPORT void GL_APIENTRY Scalef(GLfloat x, GLfloat y, GLfloat z);
 ANGLE_EXPORT void GL_APIENTRY Scalex(GLfixed x, GLfixed y, GLfixed z);
-ANGLE_EXPORT void GL_APIENTRY Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
 ANGLE_EXPORT void GL_APIENTRY ShadeModel(GLenum mode);
-ANGLE_EXPORT void GL_APIENTRY StencilFunc(GLenum func, GLint ref, GLuint mask);
-ANGLE_EXPORT void GL_APIENTRY StencilMask(GLuint mask);
-ANGLE_EXPORT void GL_APIENTRY StencilOp(GLenum fail, GLenum zfail, GLenum zpass);
 ANGLE_EXPORT void GL_APIENTRY TexCoordPointer(GLint size,
                                               GLenum type,
                                               GLsizei stride,
                                               const void *pointer);
 ANGLE_EXPORT void GL_APIENTRY TexEnvf(GLenum target, GLenum pname, GLfloat param);
 ANGLE_EXPORT void GL_APIENTRY TexEnvfv(GLenum target, GLenum pname, const GLfloat *params);
 ANGLE_EXPORT void GL_APIENTRY TexEnvi(GLenum target, GLenum pname, GLint param);
 ANGLE_EXPORT void GL_APIENTRY TexEnviv(GLenum target, GLenum pname, const GLint *params);
 ANGLE_EXPORT void GL_APIENTRY TexEnvx(GLenum target, GLenum pname, GLfixed param);
 ANGLE_EXPORT void GL_APIENTRY TexEnvxv(GLenum target, GLenum pname, const GLfixed *params);
-ANGLE_EXPORT void GL_APIENTRY TexImage2D(GLenum target,
-                                         GLint level,
-                                         GLint internalformat,
-                                         GLsizei width,
-                                         GLsizei height,
-                                         GLint border,
-                                         GLenum format,
-                                         GLenum type,
-                                         const void *pixels);
-ANGLE_EXPORT void GL_APIENTRY TexParameterf(GLenum target, GLenum pname, GLfloat param);
-ANGLE_EXPORT void GL_APIENTRY TexParameterfv(GLenum target, GLenum pname, const GLfloat *params);
-ANGLE_EXPORT void GL_APIENTRY TexParameteri(GLenum target, GLenum pname, GLint param);
-ANGLE_EXPORT void GL_APIENTRY TexParameteriv(GLenum target, GLenum pname, const GLint *params);
 ANGLE_EXPORT void GL_APIENTRY TexParameterx(GLenum target, GLenum pname, GLfixed param);
 ANGLE_EXPORT void GL_APIENTRY TexParameterxv(GLenum target, GLenum pname, const GLfixed *params);
-ANGLE_EXPORT void GL_APIENTRY TexSubImage2D(GLenum target,
-                                            GLint level,
-                                            GLint xoffset,
-                                            GLint yoffset,
-                                            GLsizei width,
-                                            GLsizei height,
-                                            GLenum format,
-                                            GLenum type,
-                                            const void *pixels);
 ANGLE_EXPORT void GL_APIENTRY Translatef(GLfloat x, GLfloat y, GLfloat z);
 ANGLE_EXPORT void GL_APIENTRY Translatex(GLfixed x, GLfixed y, GLfixed z);
 ANGLE_EXPORT void GL_APIENTRY VertexPointer(GLint size,
                                             GLenum type,
                                             GLsizei stride,
                                             const void *pointer);
-ANGLE_EXPORT void GL_APIENTRY Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
 }  // namespace gl
 
 #endif  // LIBGLESV2_ENTRY_POINTS_GLES_1_0_AUTOGEN_H_
--- a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
@@ -11,16 +11,32 @@
 #include "libGLESv2/entry_points_gles_2_0_autogen.h"
 
 #include "libANGLE/Context.h"
 #include "libANGLE/validationES2.h"
 #include "libGLESv2/global_state.h"
 
 namespace gl
 {
+void GL_APIENTRY ActiveTexture(GLenum texture)
+{
+    EVENT("(GLenum texture = 0x%X)", texture);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ActiveTexture>(texture);
+
+        if (context->skipValidation() || ValidateActiveTexture(context, texture))
+        {
+            context->activeTexture(texture);
+        }
+    }
+}
+
 void GL_APIENTRY AttachShader(GLuint program, GLuint shader)
 {
     EVENT("(GLuint program = %u, GLuint shader = %u)", program, shader);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::AttachShader>(program, shader);
@@ -44,16 +60,33 @@ void GL_APIENTRY BindAttribLocation(GLui
 
         if (context->skipValidation() || ValidateBindAttribLocation(context, program, index, name))
         {
             context->bindAttribLocation(program, index, name);
         }
     }
 }
 
+void GL_APIENTRY BindBuffer(GLenum target, GLuint buffer)
+{
+    EVENT("(GLenum target = 0x%X, GLuint buffer = %u)", target, buffer);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::BindBuffer>(targetPacked, buffer);
+
+        if (context->skipValidation() || ValidateBindBuffer(context, targetPacked, buffer))
+        {
+            context->bindBuffer(targetPacked, buffer);
+        }
+    }
+}
+
 void GL_APIENTRY BindFramebuffer(GLenum target, GLuint framebuffer)
 {
     EVENT("(GLenum target = 0x%X, GLuint framebuffer = %u)", target, framebuffer);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::BindFramebuffer>(target, framebuffer);
@@ -76,16 +109,33 @@ void GL_APIENTRY BindRenderbuffer(GLenum
 
         if (context->skipValidation() || ValidateBindRenderbuffer(context, target, renderbuffer))
         {
             context->bindRenderbuffer(target, renderbuffer);
         }
     }
 }
 
+void GL_APIENTRY BindTexture(GLenum target, GLuint texture)
+{
+    EVENT("(GLenum target = 0x%X, GLuint texture = %u)", target, texture);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::BindTexture>(targetPacked, texture);
+
+        if (context->skipValidation() || ValidateBindTexture(context, targetPacked, texture))
+        {
+            context->bindTexture(targetPacked, texture);
+        }
+    }
+}
+
 void GL_APIENTRY BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
 {
     EVENT("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red,
           green, blue, alpha);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
@@ -125,16 +175,32 @@ void GL_APIENTRY BlendEquationSeparate(G
 
         if (context->skipValidation() || ValidateBlendEquationSeparate(context, modeRGB, modeAlpha))
         {
             context->blendEquationSeparate(modeRGB, modeAlpha);
         }
     }
 }
 
+void GL_APIENTRY BlendFunc(GLenum sfactor, GLenum dfactor)
+{
+    EVENT("(GLenum sfactor = 0x%X, GLenum dfactor = 0x%X)", sfactor, dfactor);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::BlendFunc>(sfactor, dfactor);
+
+        if (context->skipValidation() || ValidateBlendFunc(context, sfactor, dfactor))
+        {
+            context->blendFunc(sfactor, dfactor);
+        }
+    }
+}
+
 void GL_APIENTRY BlendFuncSeparate(GLenum sfactorRGB,
                                    GLenum dfactorRGB,
                                    GLenum sfactorAlpha,
                                    GLenum dfactorAlpha)
 {
     EVENT(
         "(GLenum sfactorRGB = 0x%X, GLenum dfactorRGB = 0x%X, GLenum sfactorAlpha = 0x%X, GLenum "
         "dfactorAlpha = 0x%X)",
@@ -149,16 +215,59 @@ void GL_APIENTRY BlendFuncSeparate(GLenu
         if (context->skipValidation() ||
             ValidateBlendFuncSeparate(context, sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha))
         {
             context->blendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
         }
     }
 }
 
+void GL_APIENTRY BufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLsizeiptr size = %d, const void *data = 0x%0.8p, GLenum usage = "
+        "0x%X)",
+        target, size, data, usage);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        BufferUsage usagePacked    = FromGLenum<BufferUsage>(usage);
+        context->gatherParams<EntryPoint::BufferData>(targetPacked, size, data, usagePacked);
+
+        if (context->skipValidation() ||
+            ValidateBufferData(context, targetPacked, size, data, usagePacked))
+        {
+            context->bufferData(targetPacked, size, data, usagePacked);
+        }
+    }
+}
+
+void GL_APIENTRY BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const void *data = "
+        "0x%0.8p)",
+        target, offset, size, data);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::BufferSubData>(targetPacked, offset, size, data);
+
+        if (context->skipValidation() ||
+            ValidateBufferSubData(context, targetPacked, offset, size, data))
+        {
+            context->bufferSubData(targetPacked, offset, size, data);
+        }
+    }
+}
+
 GLenum GL_APIENTRY CheckFramebufferStatus(GLenum target)
 {
     EVENT("(GLenum target = 0x%X)", target);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::CheckFramebufferStatus>(target);
@@ -167,32 +276,240 @@ GLenum GL_APIENTRY CheckFramebufferStatu
         {
             return context->checkFramebufferStatus(target);
         }
     }
 
     return GetDefaultReturnValue<EntryPoint::CheckFramebufferStatus, GLenum>();
 }
 
+void GL_APIENTRY Clear(GLbitfield mask)
+{
+    EVENT("(GLbitfield mask = 0x%X)", mask);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::Clear>(mask);
+
+        if (context->skipValidation() || ValidateClear(context, mask))
+        {
+            context->clear(mask);
+        }
+    }
+}
+
+void GL_APIENTRY ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+    EVENT("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red,
+          green, blue, alpha);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ClearColor>(red, green, blue, alpha);
+
+        if (context->skipValidation() || ValidateClearColor(context, red, green, blue, alpha))
+        {
+            context->clearColor(red, green, blue, alpha);
+        }
+    }
+}
+
+void GL_APIENTRY ClearDepthf(GLfloat d)
+{
+    EVENT("(GLfloat d = %f)", d);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ClearDepthf>(d);
+
+        if (context->skipValidation() || ValidateClearDepthf(context, d))
+        {
+            context->clearDepthf(d);
+        }
+    }
+}
+
+void GL_APIENTRY ClearStencil(GLint s)
+{
+    EVENT("(GLint s = %d)", s);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ClearStencil>(s);
+
+        if (context->skipValidation() || ValidateClearStencil(context, s))
+        {
+            context->clearStencil(s);
+        }
+    }
+}
+
+void GL_APIENTRY ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+    EVENT("(GLboolean red = %u, GLboolean green = %u, GLboolean blue = %u, GLboolean alpha = %u)",
+          red, green, blue, alpha);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ColorMask>(red, green, blue, alpha);
+
+        if (context->skipValidation() || ValidateColorMask(context, red, green, blue, alpha))
+        {
+            context->colorMask(red, green, blue, alpha);
+        }
+    }
+}
+
 void GL_APIENTRY CompileShader(GLuint shader)
 {
     EVENT("(GLuint shader = %u)", shader);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::CompileShader>(shader);
 
         if (context->skipValidation() || ValidateCompileShader(context, shader))
         {
             context->compileShader(shader);
         }
     }
 }
 
+void GL_APIENTRY CompressedTexImage2D(GLenum target,
+                                      GLint level,
+                                      GLenum internalformat,
+                                      GLsizei width,
+                                      GLsizei height,
+                                      GLint border,
+                                      GLsizei imageSize,
+                                      const void *data)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = "
+        "%d, GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const void *data = "
+        "0x%0.8p)",
+        target, level, internalformat, width, height, border, imageSize, data);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        TextureTarget targetPacked = FromGLenum<TextureTarget>(target);
+        context->gatherParams<EntryPoint::CompressedTexImage2D>(
+            targetPacked, level, internalformat, width, height, border, imageSize, data);
+
+        if (context->skipValidation() ||
+            ValidateCompressedTexImage2D(context, targetPacked, level, internalformat, width,
+                                         height, border, imageSize, data))
+        {
+            context->compressedTexImage2D(targetPacked, level, internalformat, width, height,
+                                          border, imageSize, data);
+        }
+    }
+}
+
+void GL_APIENTRY CompressedTexSubImage2D(GLenum target,
+                                         GLint level,
+                                         GLint xoffset,
+                                         GLint yoffset,
+                                         GLsizei width,
+                                         GLsizei height,
+                                         GLenum format,
+                                         GLsizei imageSize,
+                                         const void *data)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, GLsizei "
+        "width = %d, GLsizei height = %d, GLenum format = 0x%X, GLsizei imageSize = %d, const void "
+        "*data = 0x%0.8p)",
+        target, level, xoffset, yoffset, width, height, format, imageSize, data);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        TextureTarget targetPacked = FromGLenum<TextureTarget>(target);
+        context->gatherParams<EntryPoint::CompressedTexSubImage2D>(
+            targetPacked, level, xoffset, yoffset, width, height, format, imageSize, data);
+
+        if (context->skipValidation() ||
+            ValidateCompressedTexSubImage2D(context, targetPacked, level, xoffset, yoffset, width,
+                                            height, format, imageSize, data))
+        {
+            context->compressedTexSubImage2D(targetPacked, level, xoffset, yoffset, width, height,
+                                             format, imageSize, data);
+        }
+    }
+}
+
+void GL_APIENTRY CopyTexImage2D(GLenum target,
+                                GLint level,
+                                GLenum internalformat,
+                                GLint x,
+                                GLint y,
+                                GLsizei width,
+                                GLsizei height,
+                                GLint border)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLint x = %d, "
+        "GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
+        target, level, internalformat, x, y, width, height, border);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        TextureTarget targetPacked = FromGLenum<TextureTarget>(target);
+        context->gatherParams<EntryPoint::CopyTexImage2D>(targetPacked, level, internalformat, x, y,
+                                                          width, height, border);
+
+        if (context->skipValidation() ||
+            ValidateCopyTexImage2D(context, targetPacked, level, internalformat, x, y, width,
+                                   height, border))
+        {
+            context->copyTexImage2D(targetPacked, level, internalformat, x, y, width, height,
+                                    border);
+        }
+    }
+}
+
+void GL_APIENTRY CopyTexSubImage2D(GLenum target,
+                                   GLint level,
+                                   GLint xoffset,
+                                   GLint yoffset,
+                                   GLint x,
+                                   GLint y,
+                                   GLsizei width,
+                                   GLsizei height)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, GLint x "
+        "= %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
+        target, level, xoffset, yoffset, x, y, width, height);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        TextureTarget targetPacked = FromGLenum<TextureTarget>(target);
+        context->gatherParams<EntryPoint::CopyTexSubImage2D>(targetPacked, level, xoffset, yoffset,
+                                                             x, y, width, height);
+
+        if (context->skipValidation() ||
+            ValidateCopyTexSubImage2D(context, targetPacked, level, xoffset, yoffset, x, y, width,
+                                      height))
+        {
+            context->copyTexSubImage2D(targetPacked, level, xoffset, yoffset, x, y, width, height);
+        }
+    }
+}
+
 GLuint GL_APIENTRY CreateProgram()
 {
     EVENT("()");
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::CreateProgram>();
@@ -208,27 +525,61 @@ GLuint GL_APIENTRY CreateProgram()
 
 GLuint GL_APIENTRY CreateShader(GLenum type)
 {
     EVENT("(GLenum type = 0x%X)", type);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::CreateShader>(type);
-
-        if (context->skipValidation() || ValidateCreateShader(context, type))
+        ShaderType typePacked = FromGLenum<ShaderType>(type);
+        context->gatherParams<EntryPoint::CreateShader>(typePacked);
+
+        if (context->skipValidation() || ValidateCreateShader(context, typePacked))
         {
-            return context->createShader(type);
+            return context->createShader(typePacked);
         }
     }
 
     return GetDefaultReturnValue<EntryPoint::CreateShader, GLuint>();
 }
 
+void GL_APIENTRY CullFace(GLenum mode)
+{
+    EVENT("(GLenum mode = 0x%X)", mode);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        CullFaceMode modePacked = FromGLenum<CullFaceMode>(mode);
+        context->gatherParams<EntryPoint::CullFace>(modePacked);
+
+        if (context->skipValidation() || ValidateCullFace(context, modePacked))
+        {
+            context->cullFace(modePacked);
+        }
+    }
+}
+
+void GL_APIENTRY DeleteBuffers(GLsizei n, const GLuint *buffers)
+{
+    EVENT("(GLsizei n = %d, const GLuint *buffers = 0x%0.8p)", n, buffers);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DeleteBuffers>(n, buffers);
+
+        if (context->skipValidation() || ValidateDeleteBuffers(context, n, buffers))
+        {
+            context->deleteBuffers(n, buffers);
+        }
+    }
+}
+
 void GL_APIENTRY DeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
 {
     EVENT("(GLsizei n = %d, const GLuint *framebuffers = 0x%0.8p)", n, framebuffers);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::DeleteFramebuffers>(n, framebuffers);
@@ -283,64 +634,227 @@ void GL_APIENTRY DeleteShader(GLuint sha
 
         if (context->skipValidation() || ValidateDeleteShader(context, shader))
         {
             context->deleteShader(shader);
         }
     }
 }
 
+void GL_APIENTRY DeleteTextures(GLsizei n, const GLuint *textures)
+{
+    EVENT("(GLsizei n = %d, const GLuint *textures = 0x%0.8p)", n, textures);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DeleteTextures>(n, textures);
+
+        if (context->skipValidation() || ValidateDeleteTextures(context, n, textures))
+        {
+            context->deleteTextures(n, textures);
+        }
+    }
+}
+
+void GL_APIENTRY DepthFunc(GLenum func)
+{
+    EVENT("(GLenum func = 0x%X)", func);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DepthFunc>(func);
+
+        if (context->skipValidation() || ValidateDepthFunc(context, func))
+        {
+            context->depthFunc(func);
+        }
+    }
+}
+
+void GL_APIENTRY DepthMask(GLboolean flag)
+{
+    EVENT("(GLboolean flag = %u)", flag);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DepthMask>(flag);
+
+        if (context->skipValidation() || ValidateDepthMask(context, flag))
+        {
+            context->depthMask(flag);
+        }
+    }
+}
+
+void GL_APIENTRY DepthRangef(GLfloat n, GLfloat f)
+{
+    EVENT("(GLfloat n = %f, GLfloat f = %f)", n, f);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DepthRangef>(n, f);
+
+        if (context->skipValidation() || ValidateDepthRangef(context, n, f))
+        {
+            context->depthRangef(n, f);
+        }
+    }
+}
+
 void GL_APIENTRY DetachShader(GLuint program, GLuint shader)
 {
     EVENT("(GLuint program = %u, GLuint shader = %u)", program, shader);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::DetachShader>(program, shader);
 
         if (context->skipValidation() || ValidateDetachShader(context, program, shader))
         {
             context->detachShader(program, shader);
         }
     }
 }
 
+void GL_APIENTRY Disable(GLenum cap)
+{
+    EVENT("(GLenum cap = 0x%X)", cap);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::Disable>(cap);
+
+        if (context->skipValidation() || ValidateDisable(context, cap))
+        {
+            context->disable(cap);
+        }
+    }
+}
+
 void GL_APIENTRY DisableVertexAttribArray(GLuint index)
 {
     EVENT("(GLuint index = %u)", index);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::DisableVertexAttribArray>(index);
 
         if (context->skipValidation() || ValidateDisableVertexAttribArray(context, index))
         {
             context->disableVertexAttribArray(index);
         }
     }
 }
 
+void GL_APIENTRY DrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+    EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DrawArrays>(mode, first, count);
+
+        if (context->skipValidation() || ValidateDrawArrays(context, mode, first, count))
+        {
+            context->drawArrays(mode, first, count);
+        }
+    }
+}
+
+void GL_APIENTRY DrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
+{
+    EVENT(
+        "(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = "
+        "0x%0.8p)",
+        mode, count, type, indices);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DrawElements>(mode, count, type, indices);
+
+        if (context->skipValidation() || ValidateDrawElements(context, mode, count, type, indices))
+        {
+            context->drawElements(mode, count, type, indices);
+        }
+    }
+}
+
+void GL_APIENTRY Enable(GLenum cap)
+{
+    EVENT("(GLenum cap = 0x%X)", cap);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::Enable>(cap);
+
+        if (context->skipValidation() || ValidateEnable(context, cap))
+        {
+            context->enable(cap);
+        }
+    }
+}
+
 void GL_APIENTRY EnableVertexAttribArray(GLuint index)
 {
     EVENT("(GLuint index = %u)", index);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::EnableVertexAttribArray>(index);
 
         if (context->skipValidation() || ValidateEnableVertexAttribArray(context, index))
         {
             context->enableVertexAttribArray(index);
         }
     }
 }
 
+void GL_APIENTRY Finish()
+{
+    EVENT("()");
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::Finish>();
+
+        if (context->skipValidation() || ValidateFinish(context))
+        {
+            context->finish();
+        }
+    }
+}
+
+void GL_APIENTRY Flush()
+{
+    EVENT("()");
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::Flush>();
+
+        if (context->skipValidation() || ValidateFlush(context))
+        {
+            context->flush();
+        }
+    }
+}
+
 void GL_APIENTRY FramebufferRenderbuffer(GLenum target,
                                          GLenum attachment,
                                          GLenum renderbuffertarget,
                                          GLuint renderbuffer)
 {
     EVENT(
         "(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, GLuint "
         "renderbuffer = %u)",
@@ -370,23 +884,57 @@ void GL_APIENTRY FramebufferTexture2D(GL
     EVENT(
         "(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, GLuint texture "
         "= %u, GLint level = %d)",
         target, attachment, textarget, texture, level);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::FramebufferTexture2D>(target, attachment, textarget,
+        TextureTarget textargetPacked = FromGLenum<TextureTarget>(textarget);
+        context->gatherParams<EntryPoint::FramebufferTexture2D>(target, attachment, textargetPacked,
                                                                 texture, level);
 
         if (context->skipValidation() ||
-            ValidateFramebufferTexture2D(context, target, attachment, textarget, texture, level))
+            ValidateFramebufferTexture2D(context, target, attachment, textargetPacked, texture,
+                                         level))
         {
-            context->framebufferTexture2D(target, attachment, textarget, texture, level);
+            context->framebufferTexture2D(target, attachment, textargetPacked, texture, level);
+        }
+    }
+}
+
+void GL_APIENTRY FrontFace(GLenum mode)
+{
+    EVENT("(GLenum mode = 0x%X)", mode);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::FrontFace>(mode);
+
+        if (context->skipValidation() || ValidateFrontFace(context, mode))
+        {
+            context->frontFace(mode);
+        }
+    }
+}
+
+void GL_APIENTRY GenBuffers(GLsizei n, GLuint *buffers)
+{
+    EVENT("(GLsizei n = %d, GLuint *buffers = 0x%0.8p)", n, buffers);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GenBuffers>(n, buffers);
+
+        if (context->skipValidation() || ValidateGenBuffers(context, n, buffers))
+        {
+            context->genBuffers(n, buffers);
         }
     }
 }
 
 void GL_APIENTRY GenFramebuffers(GLsizei n, GLuint *framebuffers)
 {
     EVENT("(GLsizei n = %d, GLuint *framebuffers = 0x%0.8p)", n, framebuffers);
 
@@ -413,28 +961,45 @@ void GL_APIENTRY GenRenderbuffers(GLsize
 
         if (context->skipValidation() || ValidateGenRenderbuffers(context, n, renderbuffers))
         {
             context->genRenderbuffers(n, renderbuffers);
         }
     }
 }
 
+void GL_APIENTRY GenTextures(GLsizei n, GLuint *textures)
+{
+    EVENT("(GLsizei n = %d, GLuint *textures = 0x%0.8p)", n, textures);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GenTextures>(n, textures);
+
+        if (context->skipValidation() || ValidateGenTextures(context, n, textures))
+        {
+            context->genTextures(n, textures);
+        }
+    }
+}
+
 void GL_APIENTRY GenerateMipmap(GLenum target)
 {
     EVENT("(GLenum target = 0x%X)", target);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::GenerateMipmap>(target);
-
-        if (context->skipValidation() || ValidateGenerateMipmap(context, target))
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::GenerateMipmap>(targetPacked);
+
+        if (context->skipValidation() || ValidateGenerateMipmap(context, targetPacked))
         {
-            context->generateMipmap(target);
+            context->generateMipmap(targetPacked);
         }
     }
 }
 
 void GL_APIENTRY GetActiveAttrib(GLuint program,
                                  GLuint index,
                                  GLsizei bufSize,
                                  GLsizei *length,
@@ -524,16 +1089,85 @@ GLint GL_APIENTRY GetAttribLocation(GLui
         {
             return context->getAttribLocation(program, name);
         }
     }
 
     return GetDefaultReturnValue<EntryPoint::GetAttribLocation, GLint>();
 }
 
+void GL_APIENTRY GetBooleanv(GLenum pname, GLboolean *data)
+{
+    EVENT("(GLenum pname = 0x%X, GLboolean *data = 0x%0.8p)", pname, data);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetBooleanv>(pname, data);
+
+        if (context->skipValidation() || ValidateGetBooleanv(context, pname, data))
+        {
+            context->getBooleanv(pname, data);
+        }
+    }
+}
+
+void GL_APIENTRY GetBufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname,
+          params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::GetBufferParameteriv>(targetPacked, pname, params);
+
+        if (context->skipValidation() ||
+            ValidateGetBufferParameteriv(context, targetPacked, pname, params))
+        {
+            context->getBufferParameteriv(targetPacked, pname, params);
+        }
+    }
+}
+
+GLenum GL_APIENTRY GetError()
+{
+    EVENT("()");
+
+    Context *context = GetGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetError>();
+
+        if (context->skipValidation() || ValidateGetError(context))
+        {
+            return context->getError();
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::GetError, GLenum>();
+}
+
+void GL_APIENTRY GetFloatv(GLenum pname, GLfloat *data)
+{
+    EVENT("(GLenum pname = 0x%X, GLfloat *data = 0x%0.8p)", pname, data);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetFloatv>(pname, data);
+
+        if (context->skipValidation() || ValidateGetFloatv(context, pname, data))
+        {
+            context->getFloatv(pname, data);
+        }
+    }
+}
+
 void GL_APIENTRY GetFramebufferAttachmentParameteriv(GLenum target,
                                                      GLenum attachment,
                                                      GLenum pname,
                                                      GLint *params)
 {
     EVENT(
         "(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint *params = "
         "0x%0.8p)",
@@ -548,16 +1182,32 @@ void GL_APIENTRY GetFramebufferAttachmen
         if (context->skipValidation() ||
             ValidateGetFramebufferAttachmentParameteriv(context, target, attachment, pname, params))
         {
             context->getFramebufferAttachmentParameteriv(target, attachment, pname, params);
         }
     }
 }
 
+void GL_APIENTRY GetIntegerv(GLenum pname, GLint *data)
+{
+    EVENT("(GLenum pname = 0x%X, GLint *data = 0x%0.8p)", pname, data);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetIntegerv>(pname, data);
+
+        if (context->skipValidation() || ValidateGetIntegerv(context, pname, data))
+        {
+            context->getIntegerv(pname, data);
+        }
+    }
+}
+
 void GL_APIENTRY GetProgramInfoLog(GLuint program,
                                    GLsizei bufSize,
                                    GLsizei *length,
                                    GLchar *infoLog)
 {
     EVENT(
         "(GLuint program = %u, GLsizei bufSize = %d, GLsizei *length = 0x%0.8p, GLchar *infoLog = "
         "0x%0.8p)",
@@ -687,16 +1337,72 @@ void GL_APIENTRY GetShaderiv(GLuint shad
 
         if (context->skipValidation() || ValidateGetShaderiv(context, shader, pname, params))
         {
             context->getShaderiv(shader, pname, params);
         }
     }
 }
 
+const GLubyte *GL_APIENTRY GetString(GLenum name)
+{
+    EVENT("(GLenum name = 0x%X)", name);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetString>(name);
+
+        if (context->skipValidation() || ValidateGetString(context, name))
+        {
+            return context->getString(name);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::GetString, const GLubyte *>();
+}
+
+void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat *params = 0x%0.8p)", target, pname,
+          params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::GetTexParameterfv>(targetPacked, pname, params);
+
+        if (context->skipValidation() ||
+            ValidateGetTexParameterfv(context, targetPacked, pname, params))
+        {
+            context->getTexParameterfv(targetPacked, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname,
+          params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::GetTexParameteriv>(targetPacked, pname, params);
+
+        if (context->skipValidation() ||
+            ValidateGetTexParameteriv(context, targetPacked, pname, params))
+        {
+            context->getTexParameteriv(targetPacked, pname, params);
+        }
+    }
+}
+
 GLint GL_APIENTRY GetUniformLocation(GLuint program, const GLchar *name)
 {
     EVENT("(GLuint program = %u, const GLchar *name = 0x%0.8p)", program, name);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::GetUniformLocation>(program, name);
@@ -791,16 +1497,68 @@ void GL_APIENTRY GetVertexAttribiv(GLuin
 
         if (context->skipValidation() || ValidateGetVertexAttribiv(context, index, pname, params))
         {
             context->getVertexAttribiv(index, pname, params);
         }
     }
 }
 
+void GL_APIENTRY Hint(GLenum target, GLenum mode)
+{
+    EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::Hint>(target, mode);
+
+        if (context->skipValidation() || ValidateHint(context, target, mode))
+        {
+            context->hint(target, mode);
+        }
+    }
+}
+
+GLboolean GL_APIENTRY IsBuffer(GLuint buffer)
+{
+    EVENT("(GLuint buffer = %u)", buffer);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::IsBuffer>(buffer);
+
+        if (context->skipValidation() || ValidateIsBuffer(context, buffer))
+        {
+            return context->isBuffer(buffer);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::IsBuffer, GLboolean>();
+}
+
+GLboolean GL_APIENTRY IsEnabled(GLenum cap)
+{
+    EVENT("(GLenum cap = 0x%X)", cap);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::IsEnabled>(cap);
+
+        if (context->skipValidation() || ValidateIsEnabled(context, cap))
+        {
+            return context->isEnabled(cap);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::IsEnabled, GLboolean>();
+}
+
 GLboolean GL_APIENTRY IsFramebuffer(GLuint framebuffer)
 {
     EVENT("(GLuint framebuffer = %u)", framebuffer);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::IsFramebuffer>(framebuffer);
@@ -863,32 +1621,124 @@ GLboolean GL_APIENTRY IsShader(GLuint sh
         {
             return context->isShader(shader);
         }
     }
 
     return GetDefaultReturnValue<EntryPoint::IsShader, GLboolean>();
 }
 
+GLboolean GL_APIENTRY IsTexture(GLuint texture)
+{
+    EVENT("(GLuint texture = %u)", texture);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::IsTexture>(texture);
+
+        if (context->skipValidation() || ValidateIsTexture(context, texture))
+        {
+            return context->isTexture(texture);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::IsTexture, GLboolean>();
+}
+
+void GL_APIENTRY LineWidth(GLfloat width)
+{
+    EVENT("(GLfloat width = %f)", width);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::LineWidth>(width);
+
+        if (context->skipValidation() || ValidateLineWidth(context, width))
+        {
+            context->lineWidth(width);
+        }
+    }
+}
+
 void GL_APIENTRY LinkProgram(GLuint program)
 {
     EVENT("(GLuint program = %u)", program);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::LinkProgram>(program);
 
         if (context->skipValidation() || ValidateLinkProgram(context, program))
         {
             context->linkProgram(program);
         }
     }
 }
 
+void GL_APIENTRY PixelStorei(GLenum pname, GLint param)
+{
+    EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::PixelStorei>(pname, param);
+
+        if (context->skipValidation() || ValidatePixelStorei(context, pname, param))
+        {
+            context->pixelStorei(pname, param);
+        }
+    }
+}
+
+void GL_APIENTRY PolygonOffset(GLfloat factor, GLfloat units)
+{
+    EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::PolygonOffset>(factor, units);
+
+        if (context->skipValidation() || ValidatePolygonOffset(context, factor, units))
+        {
+            context->polygonOffset(factor, units);
+        }
+    }
+}
+
+void GL_APIENTRY ReadPixels(GLint x,
+                            GLint y,
+                            GLsizei width,
+                            GLsizei height,
+                            GLenum format,
+                            GLenum type,
+                            void *pixels)
+{
+    EVENT(
+        "(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLenum format = "
+        "0x%X, GLenum type = 0x%X, void *pixels = 0x%0.8p)",
+        x, y, width, height, format, type, pixels);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ReadPixels>(x, y, width, height, format, type, pixels);
+
+        if (context->skipValidation() ||
+            ValidateReadPixels(context, x, y, width, height, format, type, pixels))
+        {
+            context->readPixels(x, y, width, height, format, type, pixels);
+        }
+    }
+}
+
 void GL_APIENTRY ReleaseShaderCompiler()
 {
     EVENT("()");
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::ReleaseShaderCompiler>();
@@ -919,16 +1769,49 @@ void GL_APIENTRY RenderbufferStorage(GLe
         if (context->skipValidation() ||
             ValidateRenderbufferStorage(context, target, internalformat, width, height))
         {
             context->renderbufferStorage(target, internalformat, width, height);
         }
     }
 }
 
+void GL_APIENTRY SampleCoverage(GLfloat value, GLboolean invert)
+{
+    EVENT("(GLfloat value = %f, GLboolean invert = %u)", value, invert);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::SampleCoverage>(value, invert);
+
+        if (context->skipValidation() || ValidateSampleCoverage(context, value, invert))
+        {
+            context->sampleCoverage(value, invert);
+        }
+    }
+}
+
+void GL_APIENTRY Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+    EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width,
+          height);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::Scissor>(x, y, width, height);
+
+        if (context->skipValidation() || ValidateScissor(context, x, y, width, height))
+        {
+            context->scissor(x, y, width, height);
+        }
+    }
+}
+
 void GL_APIENTRY ShaderBinary(GLsizei count,
                               const GLuint *shaders,
                               GLenum binaryformat,
                               const void *binary,
                               GLsizei length)
 {
     EVENT(
         "(GLsizei count = %d, const GLuint *shaders = 0x%0.8p, GLenum binaryformat = 0x%X, const "
@@ -967,16 +1850,32 @@ void GL_APIENTRY ShaderSource(GLuint sha
         if (context->skipValidation() ||
             ValidateShaderSource(context, shader, count, string, length))
         {
             context->shaderSource(shader, count, string, length);
         }
     }
 }
 
+void GL_APIENTRY StencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+    EVENT("(GLenum func = 0x%X, GLint ref = %d, GLuint mask = %u)", func, ref, mask);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::StencilFunc>(func, ref, mask);
+
+        if (context->skipValidation() || ValidateStencilFunc(context, func, ref, mask))
+        {
+            context->stencilFunc(func, ref, mask);
+        }
+    }
+}
+
 void GL_APIENTRY StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
 {
     EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %u)", face, func,
           ref, mask);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
@@ -985,32 +1884,64 @@ void GL_APIENTRY StencilFuncSeparate(GLe
         if (context->skipValidation() ||
             ValidateStencilFuncSeparate(context, face, func, ref, mask))
         {
             context->stencilFuncSeparate(face, func, ref, mask);
         }
     }
 }
 
+void GL_APIENTRY StencilMask(GLuint mask)
+{
+    EVENT("(GLuint mask = %u)", mask);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::StencilMask>(mask);
+
+        if (context->skipValidation() || ValidateStencilMask(context, mask))
+        {
+            context->stencilMask(mask);
+        }
+    }
+}
+
 void GL_APIENTRY StencilMaskSeparate(GLenum face, GLuint mask)
 {
     EVENT("(GLenum face = 0x%X, GLuint mask = %u)", face, mask);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::StencilMaskSeparate>(face, mask);
 
         if (context->skipValidation() || ValidateStencilMaskSeparate(context, face, mask))
         {
             context->stencilMaskSeparate(face, mask);
         }
     }
 }
 
+void GL_APIENTRY StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+    EVENT("(GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpass = 0x%X)", fail, zfail, zpass);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::StencilOp>(fail, zfail, zpass);
+
+        if (context->skipValidation() || ValidateStencilOp(context, fail, zfail, zpass))
+        {
+            context->stencilOp(fail, zfail, zpass);
+        }
+    }
+}
+
 void GL_APIENTRY StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass)
 {
     EVENT("(GLenum face = 0x%X, GLenum sfail = 0x%X, GLenum dpfail = 0x%X, GLenum dppass = 0x%X)",
           face, sfail, dpfail, dppass);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
@@ -1019,16 +1950,154 @@ void GL_APIENTRY StencilOpSeparate(GLenu
         if (context->skipValidation() ||
             ValidateStencilOpSeparate(context, face, sfail, dpfail, dppass))
         {
             context->stencilOpSeparate(face, sfail, dpfail, dppass);
         }
     }
 }
 
+void GL_APIENTRY TexImage2D(GLenum target,
+                            GLint level,
+                            GLint internalformat,
+                            GLsizei width,
+                            GLsizei height,
+                            GLint border,
+                            GLenum format,
+                            GLenum type,
+                            const void *pixels)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, "
+        "GLsizei height = %d, GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const "
+        "void *pixels = 0x%0.8p)",
+        target, level, internalformat, width, height, border, format, type, pixels);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        TextureTarget targetPacked = FromGLenum<TextureTarget>(target);
+        context->gatherParams<EntryPoint::TexImage2D>(targetPacked, level, internalformat, width,
+                                                      height, border, format, type, pixels);
+
+        if (context->skipValidation() ||
+            ValidateTexImage2D(context, targetPacked, level, internalformat, width, height, border,
+                               format, type, pixels))
+        {
+            context->texImage2D(targetPacked, level, internalformat, width, height, border, format,
+                                type, pixels);
+        }
+    }
+}
+
+void GL_APIENTRY TexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::TexParameterf>(targetPacked, pname, param);
+
+        if (context->skipValidation() || ValidateTexParameterf(context, targetPacked, pname, param))
+        {
+            context->texParameterf(targetPacked, pname, param);
+        }
+    }
+}
+
+void GL_APIENTRY TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLfloat *params = 0x%0.8p)", target,
+          pname, params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::TexParameterfv>(targetPacked, pname, params);
+
+        if (context->skipValidation() ||
+            ValidateTexParameterfv(context, targetPacked, pname, params))
+        {
+            context->texParameterfv(targetPacked, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY TexParameteri(GLenum target, GLenum pname, GLint param)
+{
+    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::TexParameteri>(targetPacked, pname, param);
+
+        if (context->skipValidation() || ValidateTexParameteri(context, targetPacked, pname, param))
+        {
+            context->texParameteri(targetPacked, pname, param);
+        }
+    }
+}
+
+void GL_APIENTRY TexParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLint *params = 0x%0.8p)", target,
+          pname, params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::TexParameteriv>(targetPacked, pname, params);
+
+        if (context->skipValidation() ||
+            ValidateTexParameteriv(context, targetPacked, pname, params))
+        {
+            context->texParameteriv(targetPacked, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY TexSubImage2D(GLenum target,
+                               GLint level,
+                               GLint xoffset,
+                               GLint yoffset,
+                               GLsizei width,
+                               GLsizei height,
+                               GLenum format,
+                               GLenum type,
+                               const void *pixels)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, GLsizei "
+        "width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, const void "
+        "*pixels = 0x%0.8p)",
+        target, level, xoffset, yoffset, width, height, format, type, pixels);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        TextureTarget targetPacked = FromGLenum<TextureTarget>(target);
+        context->gatherParams<EntryPoint::TexSubImage2D>(targetPacked, level, xoffset, yoffset,
+                                                         width, height, format, type, pixels);
+
+        if (context->skipValidation() ||
+            ValidateTexSubImage2D(context, targetPacked, level, xoffset, yoffset, width, height,
+                                  format, type, pixels))
+        {
+            context->texSubImage2D(targetPacked, level, xoffset, yoffset, width, height, format,
+                                   type, pixels);
+        }
+    }
+}
+
 void GL_APIENTRY Uniform1f(GLint location, GLfloat v0)
 {
     EVENT("(GLint location = %d, GLfloat v0 = %f)", location, v0);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::Uniform1f>(location, v0);
@@ -1543,9 +2612,26 @@ void GL_APIENTRY VertexAttribPointer(GLu
 
         if (context->skipValidation() ||
             ValidateVertexAttribPointer(context, index, size, type, normalized, stride, pointer))
         {
             context->vertexAttribPointer(index, size, type, normalized, stride, pointer);
         }
     }
 }
+
+void GL_APIENTRY Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+    EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width,
+          height);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::Viewport>(x, y, width, height);
+
+        if (context->skipValidation() || ValidateViewport(context, x, y, width, height))
+        {
+            context->viewport(x, y, width, height);
+        }
+    }
+}
 }  // namespace gl
--- a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_autogen.h
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_autogen.h
@@ -11,49 +11,120 @@
 #ifndef LIBGLESV2_ENTRY_POINTS_GLES_2_0_AUTOGEN_H_
 #define LIBGLESV2_ENTRY_POINTS_GLES_2_0_AUTOGEN_H_
 
 #include <GLES2/gl2.h>
 #include <export.h>
 
 namespace gl
 {
+ANGLE_EXPORT void GL_APIENTRY ActiveTexture(GLenum texture);
 ANGLE_EXPORT void GL_APIENTRY AttachShader(GLuint program, GLuint shader);
 ANGLE_EXPORT void GL_APIENTRY BindAttribLocation(GLuint program, GLuint index, const GLchar *name);
+ANGLE_EXPORT void GL_APIENTRY BindBuffer(GLenum target, GLuint buffer);
 ANGLE_EXPORT void GL_APIENTRY BindFramebuffer(GLenum target, GLuint framebuffer);
 ANGLE_EXPORT void GL_APIENTRY BindRenderbuffer(GLenum target, GLuint renderbuffer);
+ANGLE_EXPORT void GL_APIENTRY BindTexture(GLenum target, GLuint texture);
 ANGLE_EXPORT void GL_APIENTRY BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
 ANGLE_EXPORT void GL_APIENTRY BlendEquation(GLenum mode);
 ANGLE_EXPORT void GL_APIENTRY BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+ANGLE_EXPORT void GL_APIENTRY BlendFunc(GLenum sfactor, GLenum dfactor);
 ANGLE_EXPORT void GL_APIENTRY BlendFuncSeparate(GLenum sfactorRGB,
                                                 GLenum dfactorRGB,
                                                 GLenum sfactorAlpha,
                                                 GLenum dfactorAlpha);
+ANGLE_EXPORT void GL_APIENTRY BufferData(GLenum target,
+                                         GLsizeiptr size,
+                                         const void *data,
+                                         GLenum usage);
+ANGLE_EXPORT void GL_APIENTRY BufferSubData(GLenum target,
+                                            GLintptr offset,
+                                            GLsizeiptr size,
+                                            const void *data);
 ANGLE_EXPORT GLenum GL_APIENTRY CheckFramebufferStatus(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY Clear(GLbitfield mask);
+ANGLE_EXPORT void GL_APIENTRY ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+ANGLE_EXPORT void GL_APIENTRY ClearDepthf(GLfloat d);
+ANGLE_EXPORT void GL_APIENTRY ClearStencil(GLint s);
+ANGLE_EXPORT void GL_APIENTRY ColorMask(GLboolean red,
+                                        GLboolean green,
+                                        GLboolean blue,
+                                        GLboolean alpha);
 ANGLE_EXPORT void GL_APIENTRY CompileShader(GLuint shader);
+ANGLE_EXPORT void GL_APIENTRY CompressedTexImage2D(GLenum target,
+                                                   GLint level,
+                                                   GLenum internalformat,
+                                                   GLsizei width,
+                                                   GLsizei height,
+                                                   GLint border,
+                                                   GLsizei imageSize,
+                                                   const void *data);
+ANGLE_EXPORT void GL_APIENTRY CompressedTexSubImage2D(GLenum target,
+                                                      GLint level,
+                                                      GLint xoffset,
+                                                      GLint yoffset,
+                                                      GLsizei width,
+                                                      GLsizei height,
+                                                      GLenum format,
+                                                      GLsizei imageSize,
+                                                      const void *data);
+ANGLE_EXPORT void GL_APIENTRY CopyTexImage2D(GLenum target,
+                                             GLint level,
+                                             GLenum internalformat,
+                                             GLint x,
+                                             GLint y,
+                                             GLsizei width,
+                                             GLsizei height,
+                                             GLint border);
+ANGLE_EXPORT void GL_APIENTRY CopyTexSubImage2D(GLenum target,
+                                                GLint level,
+                                                GLint xoffset,
+                                                GLint yoffset,
+                                                GLint x,
+                                                GLint y,
+                                                GLsizei width,
+                                                GLsizei height);
 ANGLE_EXPORT GLuint GL_APIENTRY CreateProgram();
 ANGLE_EXPORT GLuint GL_APIENTRY CreateShader(GLenum type);
+ANGLE_EXPORT void GL_APIENTRY CullFace(GLenum mode);
+ANGLE_EXPORT void GL_APIENTRY DeleteBuffers(GLsizei n, const GLuint *buffers);
 ANGLE_EXPORT void GL_APIENTRY DeleteFramebuffers(GLsizei n, const GLuint *framebuffers);
 ANGLE_EXPORT void GL_APIENTRY DeleteProgram(GLuint program);
 ANGLE_EXPORT void GL_APIENTRY DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers);
 ANGLE_EXPORT void GL_APIENTRY DeleteShader(GLuint shader);
+ANGLE_EXPORT void GL_APIENTRY DeleteTextures(GLsizei n, const GLuint *textures);
+ANGLE_EXPORT void GL_APIENTRY DepthFunc(GLenum func);
+ANGLE_EXPORT void GL_APIENTRY DepthMask(GLboolean flag);
+ANGLE_EXPORT void GL_APIENTRY DepthRangef(GLfloat n, GLfloat f);
 ANGLE_EXPORT void GL_APIENTRY DetachShader(GLuint program, GLuint shader);
+ANGLE_EXPORT void GL_APIENTRY Disable(GLenum cap);
 ANGLE_EXPORT void GL_APIENTRY DisableVertexAttribArray(GLuint index);
+ANGLE_EXPORT void GL_APIENTRY DrawArrays(GLenum mode, GLint first, GLsizei count);
+ANGLE_EXPORT void GL_APIENTRY DrawElements(GLenum mode,
+                                           GLsizei count,
+                                           GLenum type,
+                                           const void *indices);
+ANGLE_EXPORT void GL_APIENTRY Enable(GLenum cap);
 ANGLE_EXPORT void GL_APIENTRY EnableVertexAttribArray(GLuint index);
+ANGLE_EXPORT void GL_APIENTRY Finish();
+ANGLE_EXPORT void GL_APIENTRY Flush();
 ANGLE_EXPORT void GL_APIENTRY FramebufferRenderbuffer(GLenum target,
                                                       GLenum attachment,
                                                       GLenum renderbuffertarget,
                                                       GLuint renderbuffer);
 ANGLE_EXPORT void GL_APIENTRY FramebufferTexture2D(GLenum target,
                                                    GLenum attachment,
                                                    GLenum textarget,
                                                    GLuint texture,
                                                    GLint level);
+ANGLE_EXPORT void GL_APIENTRY FrontFace(GLenum mode);
+ANGLE_EXPORT void GL_APIENTRY GenBuffers(GLsizei n, GLuint *buffers);
 ANGLE_EXPORT void GL_APIENTRY GenFramebuffers(GLsizei n, GLuint *framebuffers);
 ANGLE_EXPORT void GL_APIENTRY GenRenderbuffers(GLsizei n, GLuint *renderbuffers);
+ANGLE_EXPORT void GL_APIENTRY GenTextures(GLsizei n, GLuint *textures);
 ANGLE_EXPORT void GL_APIENTRY GenerateMipmap(GLenum target);
 ANGLE_EXPORT void GL_APIENTRY GetActiveAttrib(GLuint program,
                                               GLuint index,
                                               GLsizei bufSize,
                                               GLsizei *length,
                                               GLint *size,
                                               GLenum *type,
                                               GLchar *name);
@@ -64,20 +135,25 @@ ANGLE_EXPORT void GL_APIENTRY GetActiveU
                                                GLint *size,
                                                GLenum *type,
                                                GLchar *name);
 ANGLE_EXPORT void GL_APIENTRY GetAttachedShaders(GLuint program,
                                                  GLsizei maxCount,
                                                  GLsizei *count,
                                                  GLuint *shaders);
 ANGLE_EXPORT GLint GL_APIENTRY GetAttribLocation(GLuint program, const GLchar *name);
+ANGLE_EXPORT void GL_APIENTRY GetBooleanv(GLenum pname, GLboolean *data);
+ANGLE_EXPORT void GL_APIENTRY GetBufferParameteriv(GLenum target, GLenum pname, GLint *params);
+ANGLE_EXPORT GLenum GL_APIENTRY GetError();
+ANGLE_EXPORT void GL_APIENTRY GetFloatv(GLenum pname, GLfloat *data);
 ANGLE_EXPORT void GL_APIENTRY GetFramebufferAttachmentParameteriv(GLenum target,
                                                                   GLenum attachment,
                                                                   GLenum pname,
                                                                   GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GetIntegerv(GLenum pname, GLint *data);
 ANGLE_EXPORT void GL_APIENTRY GetProgramInfoLog(GLuint program,
                                                 GLsizei bufSize,
                                                 GLsizei *length,
                                                 GLchar *infoLog);
 ANGLE_EXPORT void GL_APIENTRY GetProgramiv(GLuint program, GLenum pname, GLint *params);
 ANGLE_EXPORT void GL_APIENTRY GetRenderbufferParameteriv(GLenum target,
                                                          GLenum pname,
                                                          GLint *params);
@@ -89,47 +165,91 @@ ANGLE_EXPORT void GL_APIENTRY GetShaderP
                                                        GLenum precisiontype,
                                                        GLint *range,
                                                        GLint *precision);
 ANGLE_EXPORT void GL_APIENTRY GetShaderSource(GLuint shader,
                                               GLsizei bufSize,
                                               GLsizei *length,
                                               GLchar *source);
 ANGLE_EXPORT void GL_APIENTRY GetShaderiv(GLuint shader, GLenum pname, GLint *params);
+ANGLE_EXPORT const GLubyte *GL_APIENTRY GetString(GLenum name);
+ANGLE_EXPORT void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint *params);
 ANGLE_EXPORT GLint GL_APIENTRY GetUniformLocation(GLuint program, const GLchar *name);
 ANGLE_EXPORT void GL_APIENTRY GetUniformfv(GLuint program, GLint location, GLfloat *params);
 ANGLE_EXPORT void GL_APIENTRY GetUniformiv(GLuint program, GLint location, GLint *params);
 ANGLE_EXPORT void GL_APIENTRY GetVertexAttribPointerv(GLuint index, GLenum pname, void **pointer);
 ANGLE_EXPORT void GL_APIENTRY GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
 ANGLE_EXPORT void GL_APIENTRY GetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY Hint(GLenum target, GLenum mode);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsBuffer(GLuint buffer);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsEnabled(GLenum cap);
 ANGLE_EXPORT GLboolean GL_APIENTRY IsFramebuffer(GLuint framebuffer);
 ANGLE_EXPORT GLboolean GL_APIENTRY IsProgram(GLuint program);
 ANGLE_EXPORT GLboolean GL_APIENTRY IsRenderbuffer(GLuint renderbuffer);
 ANGLE_EXPORT GLboolean GL_APIENTRY IsShader(GLuint shader);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsTexture(GLuint texture);
+ANGLE_EXPORT void GL_APIENTRY LineWidth(GLfloat width);
 ANGLE_EXPORT void GL_APIENTRY LinkProgram(GLuint program);
+ANGLE_EXPORT void GL_APIENTRY PixelStorei(GLenum pname, GLint param);
+ANGLE_EXPORT void GL_APIENTRY PolygonOffset(GLfloat factor, GLfloat units);
+ANGLE_EXPORT void GL_APIENTRY ReadPixels(GLint x,
+                                         GLint y,
+                                         GLsizei width,
+                                         GLsizei height,
+                                         GLenum format,
+                                         GLenum type,
+                                         void *pixels);
 ANGLE_EXPORT void GL_APIENTRY ReleaseShaderCompiler();
 ANGLE_EXPORT void GL_APIENTRY RenderbufferStorage(GLenum target,
                                                   GLenum internalformat,
                                                   GLsizei width,
                                                   GLsizei height);
+ANGLE_EXPORT void GL_APIENTRY SampleCoverage(GLfloat value, GLboolean invert);
+ANGLE_EXPORT void GL_APIENTRY Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
 ANGLE_EXPORT void GL_APIENTRY ShaderBinary(GLsizei count,
                                            const GLuint *shaders,
                                            GLenum binaryformat,
                                            const void *binary,
                                            GLsizei length);
 ANGLE_EXPORT void GL_APIENTRY ShaderSource(GLuint shader,
                                            GLsizei count,
                                            const GLchar *const *string,
                                            const GLint *length);
+ANGLE_EXPORT void GL_APIENTRY StencilFunc(GLenum func, GLint ref, GLuint mask);
 ANGLE_EXPORT void GL_APIENTRY StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+ANGLE_EXPORT void GL_APIENTRY StencilMask(GLuint mask);
 ANGLE_EXPORT void GL_APIENTRY StencilMaskSeparate(GLenum face, GLuint mask);
+ANGLE_EXPORT void GL_APIENTRY StencilOp(GLenum fail, GLenum zfail, GLenum zpass);
 ANGLE_EXPORT void GL_APIENTRY StencilOpSeparate(GLenum face,
                                                 GLenum sfail,
                                                 GLenum dpfail,
                                                 GLenum dppass);
+ANGLE_EXPORT void GL_APIENTRY TexImage2D(GLenum target,
+                                         GLint level,
+                                         GLint internalformat,
+                                         GLsizei width,
+                                         GLsizei height,
+                                         GLint border,
+                                         GLenum format,
+                                         GLenum type,
+                                         const void *pixels);
+ANGLE_EXPORT void GL_APIENTRY TexParameterf(GLenum target, GLenum pname, GLfloat param);
+ANGLE_EXPORT void GL_APIENTRY TexParameterfv(GLenum target, GLenum pname, const GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY TexParameteri(GLenum target, GLenum pname, GLint param);
+ANGLE_EXPORT void GL_APIENTRY TexParameteriv(GLenum target, GLenum pname, const GLint *params);
+ANGLE_EXPORT void GL_APIENTRY TexSubImage2D(GLenum target,
+                                            GLint level,
+                                            GLint xoffset,
+                                            GLint yoffset,
+                                            GLsizei width,
+                                            GLsizei height,
+                                            GLenum format,
+                                            GLenum type,
+                                            const void *pixels);
 ANGLE_EXPORT void GL_APIENTRY Uniform1f(GLint location, GLfloat v0);
 ANGLE_EXPORT void GL_APIENTRY Uniform1fv(GLint location, GLsizei count, const GLfloat *value);
 ANGLE_EXPORT void GL_APIENTRY Uniform1i(GLint location, GLint v0);
 ANGLE_EXPORT void GL_APIENTRY Uniform1iv(GLint location, GLsizei count, const GLint *value);
 ANGLE_EXPORT void GL_APIENTRY Uniform2f(GLint location, GLfloat v0, GLfloat v1);
 ANGLE_EXPORT void GL_APIENTRY Uniform2fv(GLint location, GLsizei count, const GLfloat *value);
 ANGLE_EXPORT void GL_APIENTRY Uniform2i(GLint location, GLint v0, GLint v1);
 ANGLE_EXPORT void GL_APIENTRY Uniform2iv(GLint location, GLsizei count, const GLint *value);
@@ -166,11 +286,12 @@ ANGLE_EXPORT void GL_APIENTRY
 VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
 ANGLE_EXPORT void GL_APIENTRY VertexAttrib4fv(GLuint index, const GLfloat *v);
 ANGLE_EXPORT void GL_APIENTRY VertexAttribPointer(GLuint index,
                                                   GLint size,
                                                   GLenum type,
                                                   GLboolean normalized,
                                                   GLsizei stride,
                                                   const void *pointer);
+ANGLE_EXPORT void GL_APIENTRY Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
 }  // namespace gl
 
 #endif  // LIBGLESV2_ENTRY_POINTS_GLES_2_0_AUTOGEN_H_
--- a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_ext.cpp
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_ext.cpp
@@ -28,29 +28,16 @@
 #include "libANGLE/validationES31.h"
 
 #include "common/debug.h"
 #include "common/utilities.h"
 
 namespace gl
 {
 
-namespace
-{
-
-void SetRobustLengthParam(GLsizei *length, GLsizei value)
-{
-    if (length)
-    {
-        *length = value;
-    }
-}
-
-}  // anonymous namespace
-
 ANGLE_EXPORT void GL_APIENTRY BindUniformLocationCHROMIUM(GLuint program,
                                                           GLint location,
                                                           const GLchar *name)
 {
     EVENT("(GLuint program = %u, GLint location = %d, const GLchar *name = 0x%0.8p)", program,
           location, name);
 
     Context *context = GetValidGlobalContext();
@@ -72,63 +59,63 @@ ANGLE_EXPORT void GL_APIENTRY CoverageMo
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         if (!context->skipValidation() && !ValidateCoverageModulationCHROMIUM(context, components))
         {
             return;
         }
-        context->setCoverageModulation(components);
+        context->coverageModulation(components);
     }
 }
 
 // CHROMIUM_path_rendering
 ANGLE_EXPORT void GL_APIENTRY MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat *matrix)
 {
     EVENT("(GLenum matrixMode = %u)", matrixMode);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         if (!context->skipValidation() && !ValidateMatrixLoadfCHROMIUM(context, matrixMode, matrix))
         {
             return;
         }
-        context->loadPathRenderingMatrix(matrixMode, matrix);
+        context->matrixLoadf(matrixMode, matrix);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY MatrixLoadIdentityCHROMIUM(GLenum matrixMode)
 {
     EVENT("(GLenum matrixMode = %u)", matrixMode);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         if (!context->skipValidation() && !ValidateMatrixLoadIdentityCHROMIUM(context, matrixMode))
         {
             return;
         }
-        context->loadPathRenderingIdentityMatrix(matrixMode);
+        context->matrixLoadIdentity(matrixMode);
     }
 }
 
 ANGLE_EXPORT GLuint GL_APIENTRY GenPathsCHROMIUM(GLsizei range)
 {
     EVENT("(GLsizei range = %d)", range);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         if (!context->skipValidation() && !ValidateGenPathsCHROMIUM(context, range))
         {
             return 0;
         }
-        return context->createPaths(range);
+        return context->genPaths(range);
     }
     return 0;
 }
 
 ANGLE_EXPORT void GL_APIENTRY DeletePathsCHROMIUM(GLuint first, GLsizei range)
 {
     EVENT("(GLuint first = %u, GLsizei range = %d)", first, range);
 
@@ -145,21 +132,21 @@ ANGLE_EXPORT void GL_APIENTRY DeletePath
 
 ANGLE_EXPORT GLboolean GL_APIENTRY IsPathCHROMIUM(GLuint path)
 {
     EVENT("(GLuint path = %u)", path);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!context->skipValidation() && !ValidateIsPathCHROMIUM(context))
+        if (!context->skipValidation() && !ValidateIsPathCHROMIUM(context, path))
         {
             return GL_FALSE;
         }
-        return context->hasPathData(path);
+        return context->isPath(path);
     }
     return GL_FALSE;
 }
 
 ANGLE_EXPORT void GL_APIENTRY PathCommandsCHROMIUM(GLuint path,
                                                    GLsizei numCommands,
                                                    const GLubyte *commands,
                                                    GLsizei numCoords,
@@ -175,17 +162,17 @@ ANGLE_EXPORT void GL_APIENTRY PathComman
     if (context)
     {
         if (!context->skipValidation() &&
             !ValidatePathCommandsCHROMIUM(context, path, numCommands, commands, numCoords,
                                           coordType, coords))
         {
             return;
         }
-        context->setPathCommands(path, numCommands, commands, numCoords, coordType, coords);
+        context->pathCommands(path, numCommands, commands, numCoords, coordType, coords);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY PathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat value)
 {
     EVENT("(GLuint path = %u, GLenum pname = %u, GLfloat value = %f)", path, pname, value);
 
     Context *context = GetValidGlobalContext();
@@ -257,17 +244,17 @@ ANGLE_EXPORT void GL_APIENTRY PathStenci
     Context *context = GetValidGlobalContext();
     if (context)
     {
         if (!context->skipValidation() &&
             !ValidatePathStencilFuncCHROMIUM(context, func, ref, mask))
         {
             return;
         }
-        context->setPathStencilFunc(func, ref, mask);
+        context->pathStencilFunc(func, ref, mask);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY StencilFillPathCHROMIUM(GLuint path, GLenum fillMode, GLuint mask)
 {
     EVENT("(GLuint path = %u, GLenum fillMode = %u, GLuint mask = %u)", path, fillMode, mask);
 
     Context *context = GetValidGlobalContext();
@@ -300,32 +287,33 @@ ANGLE_EXPORT void GL_APIENTRY StencilStr
 
 ANGLE_EXPORT void GL_APIENTRY CoverFillPathCHROMIUM(GLuint path, GLenum coverMode)
 {
     EVENT("(GLuint path = %u, GLenum coverMode = %u)", path, coverMode);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!context->skipValidation() && !ValidateCoverPathCHROMIUM(context, path, coverMode))
+        if (!context->skipValidation() && !ValidateCoverFillPathCHROMIUM(context, path, coverMode))
         {
             return;
         }
         context->coverFillPath(path, coverMode);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY CoverStrokePathCHROMIUM(GLuint path, GLenum coverMode)
 {
     EVENT("(GLuint path = %u, GLenum coverMode = %u)", path, coverMode);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!context->skipValidation() && !ValidateCoverPathCHROMIUM(context, path, coverMode))
+        if (!context->skipValidation() &&
+            !ValidateCoverStrokePathCHROMIUM(context, path, coverMode))
         {
             return;
         }
         context->coverStrokePath(path, coverMode);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY StencilThenCoverFillPathCHROMIUM(GLuint path,
@@ -610,26 +598,28 @@ ANGLE_EXPORT void GL_APIENTRY CopyTextur
         "0x%X, GLboolean unpackFlipY = %u, GLboolean unpackPremultiplyAlpha = %u, GLboolean "
         "unpackUnmultiplyAlpha = %u)",
         sourceId, sourceLevel, destTarget, destId, destLevel, internalFormat, destType, unpackFlipY,
         unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
+        TextureTarget destTargetPacked = FromGLenum<TextureTarget>(destTarget);
         if (!context->skipValidation() &&
-            !ValidateCopyTextureCHROMIUM(context, sourceId, sourceLevel, destTarget, destId,
+            !ValidateCopyTextureCHROMIUM(context, sourceId, sourceLevel, destTargetPacked, destId,
                                          destLevel, internalFormat, destType, unpackFlipY,
                                          unpackPremultiplyAlpha, unpackUnmultiplyAlpha))
         {
             return;
         }
 
-        context->copyTexture(sourceId, sourceLevel, destTarget, destId, destLevel, internalFormat,
-                             destType, unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
+        context->copyTexture(sourceId, sourceLevel, destTargetPacked, destId, destLevel,
+                             internalFormat, destType, unpackFlipY, unpackPremultiplyAlpha,
+                             unpackUnmultiplyAlpha);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY CopySubTextureCHROMIUM(GLuint sourceId,
                                                      GLint sourceLevel,
                                                      GLenum destTarget,
                                                      GLuint destId,
                                                      GLint destLevel,
@@ -649,25 +639,27 @@ ANGLE_EXPORT void GL_APIENTRY CopySubTex
         "%d, GLint yoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = "
         "%d, GLboolean unpackPremultiplyAlpha = %u, GLboolean unpackUnmultiplyAlpha = %u)",
         sourceId, sourceLevel, destTarget, destId, destLevel, xoffset, yoffset, x, y, width, height,
         unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
+        TextureTarget destTargetPacked = FromGLenum<TextureTarget>(destTarget);
         if (!context->skipValidation() &&
-            !ValidateCopySubTextureCHROMIUM(
-                context, sourceId, sourceLevel, destTarget, destId, destLevel, xoffset, yoffset, x,
-                y, width, height, unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha))
+            !ValidateCopySubTextureCHROMIUM(context, sourceId, sourceLevel, destTargetPacked,
+                                            destId, destLevel, xoffset, yoffset, x, y, width,
+                                            height, unpackFlipY, unpackPremultiplyAlpha,
+                                            unpackUnmultiplyAlpha))
         {
             return;
         }
 
-        context->copySubTexture(sourceId, sourceLevel, destTarget, destId, destLevel, xoffset,
+        context->copySubTexture(sourceId, sourceLevel, destTargetPacked, destId, destLevel, xoffset,
                                 yoffset, x, y, width, height, unpackFlipY, unpackPremultiplyAlpha,
                                 unpackUnmultiplyAlpha);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY CompressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
 {
     EVENT("(GLuint sourceId = %u, GLuint destId = %u)", sourceId, destId);
@@ -709,25 +701,22 @@ ANGLE_EXPORT void GL_APIENTRY GetBoolean
     EVENT(
         "(GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLboolean* params "
         "= 0x%0.8p)",
         pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLenum nativeType;
-        unsigned int numParams = 0;
-        if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
+        if (!ValidateGetBooleanvRobustANGLE(context, pname, bufSize, length, params))
         {
             return;
         }
 
-        context->getBooleanv(pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getBooleanvRobust(pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetBufferParameterivRobustANGLE(GLenum target,
                                                               GLenum pname,
                                                               GLsizei bufSize,
                                                               GLsizei *length,
                                                               GLint *params)
@@ -735,51 +724,45 @@ ANGLE_EXPORT void GL_APIENTRY GetBufferP
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname,
           params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
 
-        GLsizei numParams = 0;
-        if (!ValidateGetBufferParameterivRobustANGLE(context, targetPacked, pname, bufSize,
-                                                     &numParams, params))
+        if (!ValidateGetBufferParameterivRobustANGLE(context, targetPacked, pname, bufSize, length,
+                                                     params))
         {
             return;
         }
 
-        Buffer *buffer = context->getGLState().getTargetBuffer(targetPacked);
-        QueryBufferParameteriv(buffer, pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getBufferParameterivRobust(targetPacked, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetFloatvRobustANGLE(GLenum pname,
                                                    GLsizei bufSize,
                                                    GLsizei *length,
                                                    GLfloat *params)
 {
     EVENT(
         "(GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLfloat* params = "
         "0x%0.8p)",
         pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLenum nativeType;
-        unsigned int numParams = 0;
-        if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
+        if (!ValidateGetFloatvRobustANGLE(context, pname, bufSize, length, params))
         {
             return;
         }
 
-        context->getFloatv(pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getFloatvRobust(pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetFramebufferAttachmentParameterivRobustANGLE(GLenum target,
                                                                              GLenum attachment,
                                                                              GLenum pname,
                                                                              GLsizei bufSize,
                                                                              GLsizei *length,
@@ -788,51 +771,46 @@ ANGLE_EXPORT void GL_APIENTRY GetFramebu
     EVENT(
         "(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X,  GLsizei bufsize = "
         "%d, GLsizei* length = 0x%0.8p, GLint* params = 0x%0.8p)",
         target, attachment, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei numParams = 0;
         if (!ValidateGetFramebufferAttachmentParameterivRobustANGLE(context, target, attachment,
-                                                                    pname, bufSize, &numParams))
+                                                                    pname, bufSize, length, params))
         {
             return;
         }
 
-        const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
-        QueryFramebufferAttachmentParameteriv(context, framebuffer, attachment, pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getFramebufferAttachmentParameterivRobust(target, attachment, pname, bufSize,
+                                                           length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetIntegervRobustANGLE(GLenum pname,
                                                      GLsizei bufSize,
                                                      GLsizei *length,
                                                      GLint *data)
 {
     EVENT(
         "(GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLint* params = "
         "0x%0.8p)",
         pname, bufSize, length, data);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLenum nativeType;
-        unsigned int numParams = 0;
-        if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
+        if (!ValidateGetIntegervRobustANGLE(context, pname, bufSize, length, data))
         {
             return;
         }
 
-        context->getIntegerv(pname, data);
-        SetRobustLengthParam(length, numParams);
+        context->getIntegervRobust(pname, bufSize, length, data);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetProgramivRobustANGLE(GLuint program,
                                                       GLenum pname,
                                                       GLsizei bufSize,
                                                       GLsizei *length,
                                                       GLint *params)
@@ -840,25 +818,22 @@ ANGLE_EXPORT void GL_APIENTRY GetProgram
     EVENT(
         "(GLuint program = %d, GLenum pname = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
         "GLint* params = 0x%0.8p)",
         program, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei numParams = 0;
-        if (!ValidateGetProgramivRobustANGLE(context, program, pname, bufSize, &numParams))
+        if (!ValidateGetProgramivRobustANGLE(context, program, pname, bufSize, length, params))
         {
             return;
         }
 
-        Program *programObject = context->getProgram(program);
-        QueryProgramiv(context, programObject, pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getProgramivRobust(program, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetRenderbufferParameterivRobustANGLE(GLenum target,
                                                                     GLenum pname,
                                                                     GLsizei bufSize,
                                                                     GLsizei *length,
                                                                     GLint *params)
@@ -866,49 +841,43 @@ ANGLE_EXPORT void GL_APIENTRY GetRenderb
     EVENT(
         "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = "
         "0x%0.8p, GLint* params = 0x%0.8p)",
         target, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei numParams = 0;
-        if (!ValidateGetRenderbufferParameterivRobustANGLE(context, target, pname, bufSize,
-                                                           &numParams, params))
+        if (!ValidateGetRenderbufferParameterivRobustANGLE(context, target, pname, bufSize, length,
+                                                           params))
         {
             return;
         }
 
-        Renderbuffer *renderbuffer = context->getGLState().getCurrentRenderbuffer();
-        QueryRenderbufferiv(context, renderbuffer, pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getRenderbufferParameterivRobust(target, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY
 GetShaderivRobustANGLE(GLuint shader, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params)
 {
     EVENT(
         "(GLuint shader = %d, GLenum pname = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
         "GLint* params = 0x%0.8p)",
         shader, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei numParams = 0;
-        if (!ValidateGetShaderivRobustANGLE(context, shader, pname, bufSize, &numParams, params))
+        if (!ValidateGetShaderivRobustANGLE(context, shader, pname, bufSize, length, params))
         {
             return;
         }
 
-        Shader *shaderObject = context->getShader(shader);
-        QueryShaderiv(context, shaderObject, pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getShaderivRobust(shader, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetTexParameterfvRobustANGLE(GLenum target,
                                                            GLenum pname,
                                                            GLsizei bufSize,
                                                            GLsizei *length,
                                                            GLfloat *params)
@@ -916,26 +885,24 @@ ANGLE_EXPORT void GL_APIENTRY GetTexPara
     EVENT(
         "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = "
         "0x%0.8p, GLfloat* params = 0x%0.8p)",
         target, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei numParams = 0;
-        if (!ValidateGetTexParameterfvRobustANGLE(context, target, pname, bufSize, &numParams,
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        if (!ValidateGetTexParameterfvRobustANGLE(context, targetPacked, pname, bufSize, length,
                                                   params))
         {
             return;
         }
 
-        Texture *texture = context->getTargetTexture(target);
-        QueryTexParameterfv(texture, pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getTexParameterfvRobust(targetPacked, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetTexParameterivRobustANGLE(GLenum target,
                                                            GLenum pname,
                                                            GLsizei bufSize,
                                                            GLsizei *length,
                                                            GLint *params)
@@ -943,26 +910,24 @@ ANGLE_EXPORT void GL_APIENTRY GetTexPara
     EVENT(
         "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = "
         "0x%0.8p, GLfloat* params = 0x%0.8p)",
         target, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei numParams = 0;
-        if (!ValidateGetTexParameterivRobustANGLE(context, target, pname, bufSize, &numParams,
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        if (!ValidateGetTexParameterivRobustANGLE(context, targetPacked, pname, bufSize, length,
                                                   params))
         {
             return;
         }
 
-        Texture *texture = context->getTargetTexture(target);
-        QueryTexParameteriv(texture, pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getTexParameterivRobust(targetPacked, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetUniformfvRobustANGLE(GLuint program,
                                                       GLint location,
                                                       GLsizei bufSize,
                                                       GLsizei *length,
                                                       GLfloat *params)
@@ -970,28 +935,22 @@ ANGLE_EXPORT void GL_APIENTRY GetUniform
     EVENT(
         "(GLuint program = %d, GLint location = %d, GLsizei bufsize = %d, GLsizei* length = "
         "0x%0.8p, GLfloat* params = 0x%0.8p)",
         program, location, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei writeLength = 0;
-        if (!ValidateGetUniformfvRobustANGLE(context, program, location, bufSize, &writeLength,
-                                             params))
+        if (!ValidateGetUniformfvRobustANGLE(context, program, location, bufSize, length, params))
         {
             return;
         }
 
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-
-        programObject->getUniformfv(context, location, params);
-        SetRobustLengthParam(length, writeLength);
+        context->getUniformfvRobust(program, location, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetUniformivRobustANGLE(GLuint program,
                                                       GLint location,
                                                       GLsizei bufSize,
                                                       GLsizei *length,
                                                       GLint *params)
@@ -999,28 +958,22 @@ ANGLE_EXPORT void GL_APIENTRY GetUniform
     EVENT(
         "(GLuint program = %d, GLint location = %d, GLsizei bufsize = %d, GLsizei* length = "
         "0x%0.8p, GLint* params = 0x%0.8p)",
         program, location, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei writeLength = 0;
-        if (!ValidateGetUniformivRobustANGLE(context, program, location, bufSize, &writeLength,
-                                             params))
+        if (!ValidateGetUniformivRobustANGLE(context, program, location, bufSize, length, params))
         {
             return;
         }
 
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-
-        programObject->getUniformiv(context, location, params);
-        SetRobustLengthParam(length, writeLength);
+        context->getUniformivRobust(program, location, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetVertexAttribfvRobustANGLE(GLuint index,
                                                            GLenum pname,
                                                            GLsizei bufSize,
                                                            GLsizei *length,
                                                            GLfloat *params)
@@ -1028,25 +981,22 @@ ANGLE_EXPORT void GL_APIENTRY GetVertexA
     EVENT(
         "(GLuint index = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
         "GLfloat* params = 0x%0.8p)",
         index, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei writeLength = 0;
-        if (!ValidateGetVertexAttribfvRobustANGLE(context, index, pname, bufSize, &writeLength,
-                                                  params))
+        if (!ValidateGetVertexAttribfvRobustANGLE(context, index, pname, bufSize, length, params))
         {
             return;
         }
 
-        context->getVertexAttribfv(index, pname, params);
-        SetRobustLengthParam(length, writeLength);
+        context->getVertexAttribfvRobust(index, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetVertexAttribivRobustANGLE(GLuint index,
                                                            GLenum pname,
                                                            GLsizei bufSize,
                                                            GLsizei *length,
                                                            GLint *params)
@@ -1054,25 +1004,22 @@ ANGLE_EXPORT void GL_APIENTRY GetVertexA
     EVENT(
         "(GLuint index = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
         "GLint* params = 0x%0.8p)",
         index, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei writeLength = 0;
-        if (!ValidateGetVertexAttribivRobustANGLE(context, index, pname, bufSize, &writeLength,
-                                                  params))
+        if (!ValidateGetVertexAttribivRobustANGLE(context, index, pname, bufSize, length, params))
         {
             return;
         }
 
-        context->getVertexAttribiv(index, pname, params);
-        SetRobustLengthParam(length, writeLength);
+        context->getVertexAttribivRobust(index, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetVertexAttribPointervRobustANGLE(GLuint index,
                                                                  GLenum pname,
                                                                  GLsizei bufSize,
                                                                  GLsizei *length,
                                                                  void **pointer)
@@ -1080,25 +1027,23 @@ ANGLE_EXPORT void GL_APIENTRY GetVertexA
     EVENT(
         "(GLuint index = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
         "void** pointer = 0x%0.8p)",
         index, pname, bufSize, length, pointer);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei writeLength = 0;
-        if (!ValidateGetVertexAttribPointervRobustANGLE(context, index, pname, bufSize,
-                                                        &writeLength, pointer))
+        if (!ValidateGetVertexAttribPointervRobustANGLE(context, index, pname, bufSize, length,
+                                                        pointer))
         {
             return;
         }
 
-        context->getVertexAttribPointerv(index, pname, pointer);
-        SetRobustLengthParam(length, writeLength);
+        context->getVertexAttribPointervRobust(index, pname, bufSize, length, pointer);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY ReadPixelsRobustANGLE(GLint x,
                                                     GLint y,
                                                     GLsizei width,
                                                     GLsizei height,
                                                     GLenum format,
@@ -1113,30 +1058,24 @@ ANGLE_EXPORT void GL_APIENTRY ReadPixels
         "(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
         "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufsize = %d, GLsizei* length = "
         "0x%0.8p, GLsizei* columns = 0x%0.8p, GLsizei* rows = 0x%0.8p, void* pixels = 0x%0.8p)",
         x, y, width, height, format, type, bufSize, length, columns, rows, pixels);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei writeLength  = 0;
-        GLsizei writeColumns = 0;
-        GLsizei writeRows    = 0;
         if (!ValidateReadPixelsRobustANGLE(context, x, y, width, height, format, type, bufSize,
-                                           &writeLength, &writeColumns, &writeRows, pixels))
+                                           length, columns, rows, pixels))
         {
             return;
         }
 
-        context->readPixels(x, y, width, height, format, type, pixels);
-
-        SetRobustLengthParam(length, writeLength);
-        SetRobustLengthParam(columns, writeColumns);
-        SetRobustLengthParam(rows, writeRows);
+        context->readPixelsRobust(x, y, width, height, format, type, bufSize, length, columns, rows,
+                                  pixels);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY TexImage2DRobustANGLE(GLenum target,
                                                     GLint level,
                                                     GLint internalformat,
                                                     GLsizei width,
                                                     GLsizei height,
@@ -1150,70 +1089,71 @@ ANGLE_EXPORT void GL_APIENTRY TexImage2D
         "(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, "
         "GLsizei height = %d, GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, GLsizei "
         "bufSize = %d, const void* pixels = 0x%0.8p)",
         target, level, internalformat, width, height, border, format, type, bufSize, pixels);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!ValidateTexImage2DRobust(context, target, level, internalformat, width, height, border,
-                                      format, type, bufSize, pixels))
+        TextureTarget targetPacked = FromGLenum<TextureTarget>(target);
+        if (!ValidateTexImage2DRobust(context, targetPacked, level, internalformat, width, height,
+                                      border, format, type, bufSize, pixels))
         {
             return;
         }
 
-        context->texImage2D(target, level, internalformat, width, height, border, format, type,
-                            pixels);
+        context->texImage2DRobust(targetPacked, level, internalformat, width, height, border,
+                                  format, type, bufSize, pixels);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY TexParameterfvRobustANGLE(GLenum target,
                                                         GLenum pname,
                                                         GLsizei bufSize,
                                                         const GLfloat *params)
 {
     EVENT(
         "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLfloat* params = "
         "0x%0.8p)",
         target, pname, bufSize, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!ValidateTexParameterfvRobustANGLE(context, target, pname, bufSize, params))
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        if (!ValidateTexParameterfvRobustANGLE(context, targetPacked, pname, bufSize, params))
         {
             return;
         }
 
-        Texture *texture = context->getTargetTexture(target);
-        SetTexParameterfv(context, texture, pname, params);
+        context->texParameterfvRobust(targetPacked, pname, bufSize, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY TexParameterivRobustANGLE(GLenum target,
                                                         GLenum pname,
                                                         GLsizei bufSize,
                                                         const GLint *params)
 {
     EVENT(
         "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLfloat* params = "
         "0x%0.8p)",
         target, pname, bufSize, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!ValidateTexParameterivRobustANGLE(context, target, pname, bufSize, params))
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        if (!ValidateTexParameterivRobustANGLE(context, targetPacked, pname, bufSize, params))
         {
             return;
         }
 
-        Texture *texture = context->getTargetTexture(target);
-        SetTexParameteriv(context, texture, pname, params);
+        context->texParameterivRobust(targetPacked, pname, bufSize, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY TexSubImage2DRobustANGLE(GLenum target,
                                                        GLint level,
                                                        GLint xoffset,
                                                        GLint yoffset,
                                                        GLsizei width,
@@ -1227,24 +1167,25 @@ ANGLE_EXPORT void GL_APIENTRY TexSubImag
         "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
         "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
         "GLsizei bufsize = %d, const void* pixels = 0x%0.8p)",
         target, level, xoffset, yoffset, width, height, format, type, bufSize, pixels);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!ValidateTexSubImage2DRobustANGLE(context, target, level, xoffset, yoffset, width,
+        TextureTarget targetPacked = FromGLenum<TextureTarget>(target);
+        if (!ValidateTexSubImage2DRobustANGLE(context, targetPacked, level, xoffset, yoffset, width,
                                               height, format, type, bufSize, pixels))
         {
             return;
         }
 
-        context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type,
-                               pixels);
+        context->texSubImage2DRobust(targetPacked, level, xoffset, yoffset, width, height, format,
+                                     type, bufSize, pixels);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY TexImage3DRobustANGLE(GLenum target,
                                                     GLint level,
                                                     GLint internalformat,
                                                     GLsizei width,
                                                     GLsizei height,
@@ -1259,24 +1200,25 @@ ANGLE_EXPORT void GL_APIENTRY TexImage3D
         "(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, "
         "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLenum format = 0x%X, "
         "GLenum type = 0x%X, GLsizei bufsize = %d, const void* pixels = 0x%0.8p)",
         target, level, internalformat, width, height, depth, border, format, type, bufSize, pixels);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!ValidateTexImage3DRobustANGLE(context, target, level, internalformat, width, height,
-                                           depth, border, format, type, bufSize, pixels))
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        if (!ValidateTexImage3DRobustANGLE(context, targetPacked, level, internalformat, width,
+                                           height, depth, border, format, type, bufSize, pixels))
         {
             return;
         }
 
-        context->texImage3D(target, level, internalformat, width, height, depth, border, format,
-                            type, pixels);
+        context->texImage3DRobust(targetPacked, level, internalformat, width, height, depth, border,
+                                  format, type, bufSize, pixels);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY TexSubImage3DRobustANGLE(GLenum target,
                                                        GLint level,
                                                        GLint xoffset,
                                                        GLint yoffset,
                                                        GLint zoffset,
@@ -1294,24 +1236,26 @@ ANGLE_EXPORT void GL_APIENTRY TexSubImag
         "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufsize = %d, const void* pixels = "
         "0x%0.8p)",
         target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, bufSize,
         pixels);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!ValidateTexSubImage3DRobustANGLE(context, target, level, xoffset, yoffset, zoffset,
-                                              width, height, depth, format, type, bufSize, pixels))
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        if (!ValidateTexSubImage3DRobustANGLE(context, targetPacked, level, xoffset, yoffset,
+                                              zoffset, width, height, depth, format, type, bufSize,
+                                              pixels))
         {
             return;
         }
 
-        context->texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth,
-                               format, type, pixels);
+        context->texSubImage3DRobust(targetPacked, level, xoffset, yoffset, zoffset, width, height,
+                                     depth, format, type, bufSize, pixels);
     }
 }
 
 void GL_APIENTRY CompressedTexImage2DRobustANGLE(GLenum target,
                                                  GLint level,
                                                  GLenum internalformat,
                                                  GLsizei width,
                                                  GLsizei height,
@@ -1325,25 +1269,26 @@ void GL_APIENTRY CompressedTexImage2DRob
         "%d, "
         "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, GLsizei dataSize = %d, "
         "const GLvoid* data = 0x%0.8p)",
         target, level, internalformat, width, height, border, imageSize, dataSize, data);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!context->skipValidation() &&
-            !ValidateCompressedTexImage2DRobustANGLE(context, target, level, internalformat, width,
-                                                     height, border, imageSize, dataSize, data))
+        TextureTarget targetPacked = FromGLenum<TextureTarget>(target);
+        if (!context->skipValidation() && !ValidateCompressedTexImage2DRobustANGLE(
+                                              context, targetPacked, level, internalformat, width,
+                                              height, border, imageSize, dataSize, data))
         {
             return;
         }
 
-        context->compressedTexImage2D(target, level, internalformat, width, height, border,
-                                      imageSize, data);
+        context->compressedTexImage2DRobust(targetPacked, level, internalformat, width, height,
+                                            border, imageSize, dataSize, data);
     }
 }
 
 void GL_APIENTRY CompressedTexSubImage2DRobustANGLE(GLenum target,
                                                     GLint level,
                                                     GLint xoffset,
                                                     GLint yoffset,
                                                     GLsizei width,
@@ -1357,25 +1302,26 @@ void GL_APIENTRY CompressedTexSubImage2D
         "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
         "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
         "GLsizei imageSize = %d, GLsizei dataSize = %d, const GLvoid* data = 0x%0.8p)",
         target, level, xoffset, yoffset, width, height, format, imageSize, dataSize, data);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
+        TextureTarget targetPacked = FromGLenum<TextureTarget>(target);
         if (!context->skipValidation() && !ValidateCompressedTexSubImage2DRobustANGLE(
-                                              context, target, level, xoffset, yoffset, width,
+                                              context, targetPacked, level, xoffset, yoffset, width,
                                               height, format, imageSize, dataSize, data))
         {
             return;
         }
 
-        context->compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format,
-                                         imageSize, data);
+        context->compressedTexSubImage2DRobust(targetPacked, level, xoffset, yoffset, width, height,
+                                               format, imageSize, dataSize, data);
     }
 }
 
 void GL_APIENTRY CompressedTexImage3DRobustANGLE(GLenum target,
                                                  GLint level,
                                                  GLenum internalformat,
                                                  GLsizei width,
                                                  GLsizei height,
@@ -1390,25 +1336,26 @@ void GL_APIENTRY CompressedTexImage3DRob
         "%d, "
         "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, "
         "GLsizei dataSize = %d, const GLvoid* data = 0x%0.8p)",
         target, level, internalformat, width, height, depth, border, imageSize, dataSize, data);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
+        TextureType targetPacked = FromGLenum<TextureType>(target);
         if (!context->skipValidation() && !ValidateCompressedTexImage3DRobustANGLE(
-                                              context, target, level, internalformat, width, height,
-                                              depth, border, imageSize, dataSize, data))
+                                              context, targetPacked, level, internalformat, width,
+                                              height, depth, border, imageSize, dataSize, data))
         {
             return;
         }
 
-        context->compressedTexImage3D(target, level, internalformat, width, height, depth, border,
-                                      imageSize, data);
+        context->compressedTexImage3DRobust(targetPacked, level, internalformat, width, height,
+                                            depth, border, imageSize, dataSize, data);
     }
 }
 
 void GL_APIENTRY CompressedTexSubImage3DRobustANGLE(GLenum target,
                                                     GLint level,
                                                     GLint xoffset,
                                                     GLint yoffset,
                                                     GLint zoffset,
@@ -1426,48 +1373,48 @@ void GL_APIENTRY CompressedTexSubImage3D
         "GLenum format = 0x%X, GLsizei imageSize = %d, GLsizei dataSize = %d, const GLvoid* data = "
         "0x%0.8p)",
         target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, dataSize,
         data);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
+        TextureType targetPacked = FromGLenum<TextureType>(target);
         if (!context->skipValidation() &&
-            !ValidateCompressedTexSubImage3DRobustANGLE(context, target, level, xoffset, yoffset,
-                                                        zoffset, width, height, depth, format,
-                                                        imageSize, dataSize, data))
+            !ValidateCompressedTexSubImage3DRobustANGLE(context, targetPacked, level, xoffset,
+                                                        yoffset, zoffset, width, height, depth,
+                                                        format, imageSize, dataSize, data))
         {
             return;
         }
 
-        context->compressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height,
-                                         depth, format, imageSize, data);
+        context->compressedTexSubImage3DRobust(targetPacked, level, xoffset, yoffset, zoffset,
+                                               width, height, depth, format, imageSize, dataSize,
+                                               data);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY
 GetQueryivRobustANGLE(GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params)
 {
     EVENT(
         "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = "
         "0x%0.8p, GLint* params = 0x%0.8p)",
         target, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei numParams = 0;
-        if (!ValidateGetQueryivRobustANGLE(context, target, pname, bufSize, &numParams, params))
+        if (!ValidateGetQueryivRobustANGLE(context, target, pname, bufSize, length, params))
         {
             return;
         }
 
-        context->getQueryiv(target, pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getQueryivRobust(target, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetQueryObjectuivRobustANGLE(GLuint id,
                                                            GLenum pname,
                                                            GLsizei bufSize,
                                                            GLsizei *length,
                                                            GLuint *params)
@@ -1475,24 +1422,22 @@ ANGLE_EXPORT void GL_APIENTRY GetQueryOb
     EVENT(
         "(GLuint id = %u, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
         "GLint* params = 0x%0.8p)",
         id, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei numParams = 0;
-        if (!ValidateGetQueryObjectuivRobustANGLE(context, id, pname, bufSize, &numParams, params))
+        if (!ValidateGetQueryObjectuivRobustANGLE(context, id, pname, bufSize, length, params))
         {
             return;
         }
 
-        context->getQueryObjectuiv(id, pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getQueryObjectuivRobust(id, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetBufferPointervRobustANGLE(GLenum target,
                                                            GLenum pname,
                                                            GLsizei bufSize,
                                                            GLsizei *length,
                                                            void **params)
@@ -1502,47 +1447,43 @@ ANGLE_EXPORT void GL_APIENTRY GetBufferP
         "0x%0.8p, void** params = 0x%0.8p)",
         target, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
 
-        GLsizei numParams = 0;
-        if (!ValidateGetBufferPointervRobustANGLE(context, targetPacked, pname, bufSize, &numParams,
+        if (!ValidateGetBufferPointervRobustANGLE(context, targetPacked, pname, bufSize, length,
                                                   params))
         {
             return;
         }
 
-        context->getBufferPointerv(targetPacked, pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getBufferPointervRobust(targetPacked, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY
 GetIntegeri_vRobustANGLE(GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint *data)
 {
     EVENT(
         "(GLenum target = 0x%X, GLuint index = %u, GLsizei bufsize = %d, GLsizei* length = "
         "0x%0.8p, GLint* data = 0x%0.8p)",
         target, index, bufSize, length, data);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei numParams = 0;
-        if (!ValidateGetIntegeri_vRobustANGLE(context, target, index, bufSize, &numParams, data))
+        if (!ValidateGetIntegeri_vRobustANGLE(context, target, index, bufSize, length, data))
         {
             return;
         }
 
-        context->getIntegeri_v(target, index, data);
-        SetRobustLengthParam(length, numParams);
+        context->getIntegeri_vRobust(target, index, bufSize, length, data);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetInternalformativRobustANGLE(GLenum target,
                                                              GLenum internalformat,
                                                              GLenum pname,
                                                              GLsizei bufSize,
                                                              GLsizei *length,
@@ -1551,26 +1492,23 @@ ANGLE_EXPORT void GL_APIENTRY GetInterna
     EVENT(
         "(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize "
         "= %d, GLsizei* length = 0x%0.8p, GLint* params = 0x%0.8p)",
         target, internalformat, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei numParams = 0;
         if (!ValidateGetInternalFormativRobustANGLE(context, target, internalformat, pname, bufSize,
-                                                    &numParams, params))
+                                                    length, params))
         {
             return;
         }
 
-        const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
-        QueryInternalFormativ(formatCaps, pname, bufSize, params);
-        SetRobustLengthParam(length, numParams);
+        context->getInternalformativRobust(target, internalformat, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIivRobustANGLE(GLuint index,
                                                             GLenum pname,
                                                             GLsizei bufSize,
                                                             GLsizei *length,
                                                             GLint *params)
@@ -1578,25 +1516,22 @@ ANGLE_EXPORT void GL_APIENTRY GetVertexA
     EVENT(
         "(GLuint index = %u, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
         "GLint* params = 0x%0.8p)",
         index, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei writeLength = 0;
-        if (!ValidateGetVertexAttribIivRobustANGLE(context, index, pname, bufSize, &writeLength,
-                                                   params))
+        if (!ValidateGetVertexAttribIivRobustANGLE(context, index, pname, bufSize, length, params))
         {
             return;
         }
 
-        context->getVertexAttribIiv(index, pname, params);
-        SetRobustLengthParam(length, writeLength);
+        context->getVertexAttribIivRobust(index, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIuivRobustANGLE(GLuint index,
                                                              GLenum pname,
                                                              GLsizei bufSize,
                                                              GLsizei *length,
                                                              GLuint *params)
@@ -1604,25 +1539,22 @@ ANGLE_EXPORT void GL_APIENTRY GetVertexA
     EVENT(
         "(GLuint index = %u, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
         "GLuint* params = 0x%0.8p)",
         index, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei writeLength = 0;
-        if (!ValidateGetVertexAttribIuivRobustANGLE(context, index, pname, bufSize, &writeLength,
-                                                    params))
+        if (!ValidateGetVertexAttribIuivRobustANGLE(context, index, pname, bufSize, length, params))
         {
             return;
         }
 
-        context->getVertexAttribIuiv(index, pname, params);
-        SetRobustLengthParam(length, writeLength);
+        context->getVertexAttribIuivRobust(index, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetUniformuivRobustANGLE(GLuint program,
                                                        GLint location,
                                                        GLsizei bufSize,
                                                        GLsizei *length,
                                                        GLuint *params)
@@ -1630,28 +1562,22 @@ ANGLE_EXPORT void GL_APIENTRY GetUniform
     EVENT(
         "(GLuint program = %u, GLint location = %d, GLsizei bufsize = %d, GLsizei* length = "
         "0x%0.8p, GLuint* params = 0x%0.8p)",
         program, location, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei writeLength = 0;
-        if (!ValidateGetUniformuivRobustANGLE(context, program, location, bufSize, &writeLength,
-                                              params))
+        if (!ValidateGetUniformuivRobustANGLE(context, program, location, bufSize, length, params))
         {
             return;
         }
 
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-
-        programObject->getUniformuiv(context, location, params);
-        SetRobustLengthParam(length, writeLength);
+        context->getUniformuivRobust(program, location, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetActiveUniformBlockivRobustANGLE(GLuint program,
                                                                  GLuint uniformBlockIndex,
                                                                  GLenum pname,
                                                                  GLsizei bufSize,
                                                                  GLsizei *length,
@@ -1660,58 +1586,46 @@ ANGLE_EXPORT void GL_APIENTRY GetActiveU
     EVENT(
         "(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLsizei bufsize "
         "= %d, GLsizei* length = 0x%0.8p, GLint* params = 0x%0.8p)",
         program, uniformBlockIndex, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei writeLength = 0;
         if (!ValidateGetActiveUniformBlockivRobustANGLE(context, program, uniformBlockIndex, pname,
-                                                        bufSize, &writeLength, params))
+                                                        bufSize, length, params))
         {
             return;
         }
 
-        const Program *programObject = context->getProgram(program);
-        QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
-        SetRobustLengthParam(length, writeLength);
+        context->getActiveUniformBlockivRobust(program, uniformBlockIndex, pname, bufSize, length,
+                                               params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetInteger64vRobustANGLE(GLenum pname,
                                                        GLsizei bufSize,
                                                        GLsizei *length,
                                                        GLint64 *data)
 {
     EVENT(
         "(GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLint64* params = "
         "0x%0.8p)",
         pname, bufSize, length, data);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLenum nativeType;
-        unsigned int numParams = 0;
-        if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
+        if (!ValidateGetInteger64vRobustANGLE(context, pname, bufSize, length, data))
         {
             return;
         }
 
-        if (nativeType == GL_INT_64_ANGLEX)
-        {
-            context->getInteger64v(pname, data);
-        }
-        else
-        {
-            CastStateValues(context, nativeType, pname, numParams, data);
-        }
-        SetRobustLengthParam(length, numParams);
+        context->getInteger64vRobust(pname, bufSize, length, data);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetInteger64i_vRobustANGLE(GLenum target,
                                                          GLuint index,
                                                          GLsizei bufSize,
                                                          GLsizei *length,
                                                          GLint64 *data)
@@ -1719,24 +1633,22 @@ ANGLE_EXPORT void GL_APIENTRY GetInteger
     EVENT(
         "(GLenum target = 0x%X, GLuint index = %u, GLsizei bufsize = %d, GLsizei* length = "
         "0x%0.8p, GLint64* data = 0x%0.8p)",
         target, index, bufSize, length, data);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei numParams = 0;
-        if (!ValidateGetInteger64i_vRobustANGLE(context, target, index, bufSize, &numParams, data))
+        if (!ValidateGetInteger64i_vRobustANGLE(context, target, index, bufSize, length, data))
         {
             return;
         }
 
-        context->getInteger64i_v(target, index, data);
-        SetRobustLengthParam(length, numParams);
+        context->getInteger64i_vRobust(target, index, bufSize, length, data);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetBufferParameteri64vRobustANGLE(GLenum target,
                                                                 GLenum pname,
                                                                 GLsizei bufSize,
                                                                 GLsizei *length,
                                                                 GLint64 *params)
@@ -1744,26 +1656,23 @@ ANGLE_EXPORT void GL_APIENTRY GetBufferP
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64* params = 0x%0.8p)", target, pname,
           bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
 
-        GLsizei numParams = 0;
         if (!ValidateGetBufferParameteri64vRobustANGLE(context, targetPacked, pname, bufSize,
-                                                       &numParams, params))
+                                                       length, params))
         {
             return;
         }
 
-        Buffer *buffer = context->getGLState().getTargetBuffer(targetPacked);
-        QueryBufferParameteri64v(buffer, pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getBufferParameteri64vRobust(targetPacked, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY SamplerParameterivRobustANGLE(GLuint sampler,
                                                             GLenum pname,
                                                             GLsizei bufSize,
                                                             const GLint *param)
 {
@@ -1775,17 +1684,17 @@ ANGLE_EXPORT void GL_APIENTRY SamplerPar
     Context *context = GetValidGlobalContext();
     if (context)
     {
         if (!ValidateSamplerParameterivRobustANGLE(context, sampler, pname, bufSize, param))
         {
             return;
         }
 
-        context->samplerParameteriv(sampler, pname, param);
+        context->samplerParameterivRobust(sampler, pname, bufSize, param);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY SamplerParameterfvRobustANGLE(GLuint sampler,
                                                             GLenum pname,
                                                             GLsizei bufSize,
                                                             const GLfloat *param)
 {
@@ -1797,17 +1706,17 @@ ANGLE_EXPORT void GL_APIENTRY SamplerPar
     Context *context = GetValidGlobalContext();
     if (context)
     {
         if (!ValidateSamplerParameterfvRobustANGLE(context, sampler, pname, bufSize, param))
         {
             return;
         }
 
-        context->samplerParameterfv(sampler, pname, param);
+        context->samplerParameterfvRobust(sampler, pname, bufSize, param);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterivRobustANGLE(GLuint sampler,
                                                                GLenum pname,
                                                                GLsizei bufSize,
                                                                GLsizei *length,
                                                                GLint *params)
@@ -1815,25 +1724,23 @@ ANGLE_EXPORT void GL_APIENTRY GetSampler
     EVENT(
         "(GLuint sampler = %u, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = "
         "0x%0.8p, GLint* params = 0x%0.8p)",
         sampler, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei numParams = 0;
-        if (!ValidateGetSamplerParameterivRobustANGLE(context, sampler, pname, bufSize, &numParams,
+        if (!ValidateGetSamplerParameterivRobustANGLE(context, sampler, pname, bufSize, length,
                                                       params))
         {
             return;
         }
 
-        context->getSamplerParameteriv(sampler, pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getSamplerParameterivRobust(sampler, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterfvRobustANGLE(GLuint sampler,
                                                                GLenum pname,
                                                                GLsizei bufSize,
                                                                GLsizei *length,
                                                                GLfloat *params)
@@ -1841,25 +1748,23 @@ ANGLE_EXPORT void GL_APIENTRY GetSampler
     EVENT(
         "(GLuint sample = %ur, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = "
         "0x%0.8p, GLfloat* params = 0x%0.8p)",
         sampler, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei numParams = 0;
-        if (!ValidateGetSamplerParameterfvRobustANGLE(context, sampler, pname, bufSize, &numParams,
+        if (!ValidateGetSamplerParameterfvRobustANGLE(context, sampler, pname, bufSize, length,
                                                       params))
         {
             return;
         }
 
-        context->getSamplerParameterfv(sampler, pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getSamplerParameterfvRobust(sampler, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetFramebufferParameterivRobustANGLE(GLenum target,
                                                                    GLenum pname,
                                                                    GLsizei bufSize,
                                                                    GLsizei *length,
                                                                    GLint *params)
@@ -1893,24 +1798,22 @@ ANGLE_EXPORT void GL_APIENTRY GetBoolean
 {
     EVENT(
         "(GLenum target = 0x%X, GLuint index = %u, GLsizei bufsize = %d, GLsizei* length = "
         "0x%0.8p, GLboolean* data = 0x%0.8p)",
         target, index, bufSize, length, data);
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei numParams = 0;
-        if (!ValidateGetBooleani_vRobustANGLE(context, target, index, bufSize, &numParams, data))
+        if (!ValidateGetBooleani_vRobustANGLE(context, target, index, bufSize, length, data))
         {
             return;
         }
 
-        context->getBooleani_v(target, index, data);
-        SetRobustLengthParam(length, numParams);
+        context->getBooleani_vRobust(target, index, bufSize, length, data);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetMultisamplefvRobustANGLE(GLenum pname,
                                                           GLuint index,
                                                           GLsizei bufSize,
                                                           GLsizei *length,
                                                           GLfloat *val)
@@ -1978,30 +1881,24 @@ ANGLE_EXPORT void GL_APIENTRY ReadnPixel
         "(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
         "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufsize = %d, GLsizei* length = "
         "0x%0.8p, GLsizei* columns = 0x%0.8p, GLsizei* rows = 0x%0.8p, void *data = 0x%0.8p)",
         x, y, width, height, format, type, bufSize, length, columns, rows, data);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei writeLength  = 0;
-        GLsizei writeColumns = 0;
-        GLsizei writeRows    = 0;
         if (!ValidateReadnPixelsRobustANGLE(context, x, y, width, height, format, type, bufSize,
-                                            &writeLength, &writeColumns, &writeRows, data))
+                                            length, columns, rows, data))
         {
             return;
         }
 
-        context->readPixels(x, y, width, height, format, type, data);
-
-        SetRobustLengthParam(length, writeLength);
-        SetRobustLengthParam(columns, writeColumns);
-        SetRobustLengthParam(rows, writeRows);
+        context->readnPixelsRobust(x, y, width, height, format, type, bufSize, length, columns,
+                                   rows, data);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetnUniformfvRobustANGLE(GLuint program,
                                                        GLint location,
                                                        GLsizei bufSize,
                                                        GLsizei *length,
                                                        GLfloat *params)
@@ -2148,24 +2045,22 @@ ANGLE_EXPORT void GL_APIENTRY GetQueryOb
     EVENT(
         "(GLuint id = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
         "GLuint *params = 0x%0.8p)",
         id, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei numParams = 0;
-        if (!ValidateGetQueryObjectivRobustANGLE(context, id, pname, bufSize, &numParams, params))
+        if (!ValidateGetQueryObjectivRobustANGLE(context, id, pname, bufSize, length, params))
         {
             return;
         }
 
-        context->getQueryObjectiv(id, pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getQueryObjectivRobust(id, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetQueryObjecti64vRobustANGLE(GLuint id,
                                                             GLenum pname,
                                                             GLsizei bufSize,
                                                             GLsizei *length,
                                                             GLint64 *params)
@@ -2173,24 +2068,22 @@ ANGLE_EXPORT void GL_APIENTRY GetQueryOb
     EVENT(
         "(GLuint id = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
         "GLint64 *params = 0x%0.8p)",
         id, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei numParams = 0;
-        if (!ValidateGetQueryObjecti64vRobustANGLE(context, id, pname, bufSize, &numParams, params))
+        if (!ValidateGetQueryObjecti64vRobustANGLE(context, id, pname, bufSize, length, params))
         {
             return;
         }
 
-        context->getQueryObjecti64v(id, pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getQueryObjecti64vRobust(id, pname, bufSize, length, params);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetQueryObjectui64vRobustANGLE(GLuint id,
                                                              GLenum pname,
                                                              GLsizei bufSize,
                                                              GLsizei *length,
                                                              GLuint64 *params)
@@ -2198,25 +2091,22 @@ ANGLE_EXPORT void GL_APIENTRY GetQueryOb
     EVENT(
         "(GLuint id = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
         "GLuint64 *params = 0x%0.8p)",
         id, pname, bufSize, length, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        GLsizei numParams = 0;
-        if (!ValidateGetQueryObjectui64vRobustANGLE(context, id, pname, bufSize, &numParams,
-                                                    params))
+        if (!ValidateGetQueryObjectui64vRobustANGLE(context, id, pname, bufSize, length, params))
         {
             return;
         }
 
-        context->getQueryObjectui64v(id, pname, params);
-        SetRobustLengthParam(length, numParams);
+        context->getQueryObjectui64vRobust(id, pname, bufSize, length, params);
     }
 }
 
 GL_APICALL void GL_APIENTRY FramebufferTextureMultiviewLayeredANGLE(GLenum target,
                                                                     GLenum attachment,
                                                                     GLuint texture,
                                                                     GLint level,
                                                                     GLint baseViewIndex,
@@ -2230,18 +2120,18 @@ GL_APICALL void GL_APIENTRY FramebufferT
     if (context)
     {
         if (!context->skipValidation() &&
             !ValidateFramebufferTextureMultiviewLayeredANGLE(context, target, attachment, texture,
                                                              level, baseViewIndex, numViews))
         {
             return;
         }
-        context->framebufferTextureMultiviewLayeredANGLE(target, attachment, texture, level,
-                                                         baseViewIndex, numViews);
+        context->framebufferTextureMultiviewLayered(target, attachment, texture, level,
+                                                    baseViewIndex, numViews);
     }
 }
 
 GL_APICALL void GL_APIENTRY FramebufferTextureMultiviewSideBySideANGLE(GLenum target,
                                                                        GLenum attachment,
                                                                        GLuint texture,
                                                                        GLint level,
                                                                        GLsizei numViews,
@@ -2255,14 +2145,14 @@ GL_APICALL void GL_APIENTRY FramebufferT
     if (context)
     {
         if (!context->skipValidation() &&
             !ValidateFramebufferTextureMultiviewSideBySideANGLE(
                 context, target, attachment, texture, level, numViews, viewportOffsets))
         {
             return;
         }
-        context->framebufferTextureMultiviewSideBySideANGLE(target, attachment, texture, level,
-                                                            numViews, viewportOffsets);
+        context->framebufferTextureMultiviewSideBySide(target, attachment, texture, level, numViews,
+                                                       viewportOffsets);
     }
 }
 
 }  // gl
--- a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_0_autogen.cpp
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_0_autogen.cpp
@@ -272,24 +272,25 @@ void GL_APIENTRY CompressedTexImage3D(GL
         "(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = "
         "%d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, "
         "const void *data = 0x%0.8p)",
         target, level, internalformat, width, height, depth, border, imageSize, data);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
+        TextureType targetPacked = FromGLenum<TextureType>(target);
         context->gatherParams<EntryPoint::CompressedTexImage3D>(
-            target, level, internalformat, width, height, depth, border, imageSize, data);
+            targetPacked, level, internalformat, width, height, depth, border, imageSize, data);
 
         if (context->skipValidation() ||
-            ValidateCompressedTexImage3D(context, target, level, internalformat, width, height,
-                                         depth, border, imageSize, data))
+            ValidateCompressedTexImage3D(context, targetPacked, level, internalformat, width,
+                                         height, depth, border, imageSize, data))
         {
-            context->compressedTexImage3D(target, level, internalformat, width, height, depth,
+            context->compressedTexImage3D(targetPacked, level, internalformat, width, height, depth,
                                           border, imageSize, data);
         }
     }
 }
 
 void GL_APIENTRY CompressedTexSubImage3D(GLenum target,
                                          GLint level,
                                          GLint xoffset,
@@ -306,25 +307,26 @@ void GL_APIENTRY CompressedTexSubImage3D
         "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, GLint "
         "zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLenum format "
         "= 0x%X, GLsizei imageSize = %d, const void *data = 0x%0.8p)",
         target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::CompressedTexSubImage3D>(target, level, xoffset, yoffset,
-                                                                   zoffset, width, height, depth,
-                                                                   format, imageSize, data);
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::CompressedTexSubImage3D>(targetPacked, level, xoffset,
+                                                                   yoffset, zoffset, width, height,
+                                                                   depth, format, imageSize, data);
 
         if (context->skipValidation() ||
-            ValidateCompressedTexSubImage3D(context, target, level, xoffset, yoffset, zoffset,
+            ValidateCompressedTexSubImage3D(context, targetPacked, level, xoffset, yoffset, zoffset,
                                             width, height, depth, format, imageSize, data))
         {
-            context->compressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width,
+            context->compressedTexSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, width,
                                              height, depth, format, imageSize, data);
         }
     }
 }
 
 void GL_APIENTRY CopyBufferSubData(GLenum readTarget,
                                    GLenum writeTarget,
                                    GLintptr readOffset,
@@ -367,24 +369,25 @@ void GL_APIENTRY CopyTexSubImage3D(GLenu
     EVENT(
         "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, GLint "
         "zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
         target, level, xoffset, yoffset, zoffset, x, y, width, height);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::CopyTexSubImage3D>(target, level, xoffset, yoffset,
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::CopyTexSubImage3D>(targetPacked, level, xoffset, yoffset,
                                                              zoffset, x, y, width, height);
 
         if (context->skipValidation() ||
-            ValidateCopyTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, x, y,
+            ValidateCopyTexSubImage3D(context, targetPacked, level, xoffset, yoffset, zoffset, x, y,
                                       width, height))
         {
-            context->copyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width,
+            context->copyTexSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, x, y, width,
                                        height);
         }
     }
 }
 
 void GL_APIENTRY DeleteQueries(GLsizei n, const GLuint *ids)
 {
     EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
@@ -1528,47 +1531,49 @@ void GL_APIENTRY TexImage3D(GLenum targe
         "(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, "
         "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLenum format = 0x%X, GLenum "
         "type = 0x%X, const void *pixels = 0x%0.8p)",
         target, level, internalformat, width, height, depth, border, format, type, pixels);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::TexImage3D>(target, level, internalformat, width, height,
-                                                      depth, border, format, type, pixels);
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::TexImage3D>(targetPacked, level, internalformat, width,
+                                                      height, depth, border, format, type, pixels);
 
         if (context->skipValidation() ||
-            ValidateTexImage3D(context, target, level, internalformat, width, height, depth, border,
-                               format, type, pixels))
+            ValidateTexImage3D(context, targetPacked, level, internalformat, width, height, depth,
+                               border, format, type, pixels))
         {
-            context->texImage3D(target, level, internalformat, width, height, depth, border, format,
-                                type, pixels);
+            context->texImage3D(targetPacked, level, internalformat, width, height, depth, border,
+                                format, type, pixels);
         }
     }
 }
 
 void GL_APIENTRY
 TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
 {
     EVENT(
         "(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = "
         "%d, GLsizei height = %d)",
         target, levels, internalformat, width, height);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::TexStorage2D>(target, levels, internalformat, width,
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::TexStorage2D>(targetPacked, levels, internalformat, width,
                                                         height);
 
         if (context->skipValidation() ||
-            ValidateTexStorage2D(context, target, levels, internalformat, width, height))
+            ValidateTexStorage2D(context, targetPacked, levels, internalformat, width, height))
         {
-            context->texStorage2D(target, levels, internalformat, width, height);
+            context->texStorage2D(targetPacked, levels, internalformat, width, height);
         }
     }
 }
 
 void GL_APIENTRY TexStorage3D(GLenum target,
                               GLsizei levels,
                               GLenum internalformat,
                               GLsizei width,
@@ -1578,23 +1583,24 @@ void GL_APIENTRY TexStorage3D(GLenum tar
     EVENT(
         "(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = "
         "%d, GLsizei height = %d, GLsizei depth = %d)",
         target, levels, internalformat, width, height, depth);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::TexStorage3D>(target, levels, internalformat, width,
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::TexStorage3D>(targetPacked, levels, internalformat, width,
                                                         height, depth);
 
-        if (context->skipValidation() ||
-            ValidateTexStorage3D(context, target, levels, internalformat, width, height, depth))
+        if (context->skipValidation() || ValidateTexStorage3D(context, targetPacked, levels,
+                                                              internalformat, width, height, depth))
         {
-            context->texStorage3D(target, levels, internalformat, width, height, depth);
+            context->texStorage3D(targetPacked, levels, internalformat, width, height, depth);
         }
     }
 }
 
 void GL_APIENTRY TexSubImage3D(GLenum target,
                                GLint level,
                                GLint xoffset,
                                GLint yoffset,
@@ -1610,25 +1616,27 @@ void GL_APIENTRY TexSubImage3D(GLenum ta
         "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, GLint "
         "zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLenum format "
         "= 0x%X, GLenum type = 0x%X, const void *pixels = 0x%0.8p)",
         target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::TexSubImage3D>(
-            target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::TexSubImage3D>(targetPacked, level, xoffset, yoffset,
+                                                         zoffset, width, height, depth, format,
+                                                         type, pixels);
 
         if (context->skipValidation() ||
-            ValidateTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, width, height,
-                                  depth, format, type, pixels))
+            ValidateTexSubImage3D(context, targetPacked, level, xoffset, yoffset, zoffset, width,
+                                  height, depth, format, type, pixels))
         {
-            context->texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth,
-                                   format, type, pixels);
+            context->texSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, width, height,
+                                   depth, format, type, pixels);
         }
     }
 }
 
 void GL_APIENTRY TransformFeedbackVaryings(GLuint program,
                                            GLsizei count,
                                            const GLchar *const *varyings,
                                            GLenum bufferMode)
--- a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_1_autogen.cpp
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_1_autogen.cpp
@@ -100,22 +100,23 @@ void GL_APIENTRY BindVertexBuffer(GLuint
 GLuint GL_APIENTRY CreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings)
 {
     EVENT("(GLenum type = 0x%X, GLsizei count = %d, const GLchar *const*strings = 0x%0.8p)", type,
           count, strings);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::CreateShaderProgramv>(type, count, strings);
+        ShaderType typePacked = FromGLenum<ShaderType>(type);
+        context->gatherParams<EntryPoint::CreateShaderProgramv>(typePacked, count, strings);
 
         if (context->skipValidation() ||
-            ValidateCreateShaderProgramv(context, type, count, strings))
+            ValidateCreateShaderProgramv(context, typePacked, count, strings))
         {
-            return context->createShaderProgramv(type, count, strings);
+            return context->createShaderProgramv(typePacked, count, strings);
         }
     }
 
     return GetDefaultReturnValue<EntryPoint::CreateShaderProgramv, GLuint>();
 }
 
 void GL_APIENTRY DeleteProgramPipelines(GLsizei n, const GLuint *pipelines)
 {
@@ -460,40 +461,44 @@ void GL_APIENTRY GetTexLevelParameterfv(
 {
     EVENT(
         "(GLenum target = 0x%X, GLint level = %d, GLenum pname = 0x%X, GLfloat *params = 0x%0.8p)",
         target, level, pname, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::GetTexLevelParameterfv>(target, level, pname, params);
+        TextureTarget targetPacked = FromGLenum<TextureTarget>(target);
+        context->gatherParams<EntryPoint::GetTexLevelParameterfv>(targetPacked, level, pname,
+                                                                  params);
 
         if (context->skipValidation() ||
-            ValidateGetTexLevelParameterfv(context, target, level, pname, params))
+            ValidateGetTexLevelParameterfv(context, targetPacked, level, pname, params))
         {
-            context->getTexLevelParameterfv(target, level, pname, params);
+            context->getTexLevelParameterfv(targetPacked, level, pname, params);
         }
     }
 }
 
 void GL_APIENTRY GetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
 {
     EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)",
           target, level, pname, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::GetTexLevelParameteriv>(target, level, pname, params);
+        TextureTarget targetPacked = FromGLenum<TextureTarget>(target);
+        context->gatherParams<EntryPoint::GetTexLevelParameteriv>(targetPacked, level, pname,
+                                                                  params);
 
         if (context->skipValidation() ||
-            ValidateGetTexLevelParameteriv(context, target, level, pname, params))
+            ValidateGetTexLevelParameteriv(context, targetPacked, level, pname, params))
         {
-            context->getTexLevelParameteriv(target, level, pname, params);
+            context->getTexLevelParameteriv(targetPacked, level, pname, params);
         }
     }
 }
 
 GLboolean GL_APIENTRY IsProgramPipeline(GLuint pipeline)
 {
     EVENT("(GLuint pipeline = %u)", pipeline);
 
@@ -1294,24 +1299,25 @@ void GL_APIENTRY TexStorage2DMultisample
     EVENT(
         "(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width "
         "= %d, GLsizei height = %d, GLboolean fixedsamplelocations = %u)",
         target, samples, internalformat, width, height, fixedsamplelocations);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
+        TextureType targetPacked = FromGLenum<TextureType>(target);
         context->gatherParams<EntryPoint::TexStorage2DMultisample>(
-            target, samples, internalformat, width, height, fixedsamplelocations);
+            targetPacked, samples, internalformat, width, height, fixedsamplelocations);
 
         if (context->skipValidation() ||
-            ValidateTexStorage2DMultisample(context, target, samples, internalformat, width, height,
-                                            fixedsamplelocations))
+            ValidateTexStorage2DMultisample(context, targetPacked, samples, internalformat, width,
+                                            height, fixedsamplelocations))
         {
-            context->texStorage2DMultisample(target, samples, internalformat, width, height,
+            context->texStorage2DMultisample(targetPacked, samples, internalformat, width, height,
                                              fixedsamplelocations);
         }
     }
 }
 
 void GL_APIENTRY UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
 {
     EVENT("(GLuint pipeline = %u, GLbitfield stages = 0x%X, GLuint program = %u)", pipeline, stages,
--- a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_ext_autogen.cpp
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_ext_autogen.cpp
@@ -623,23 +623,24 @@ TexStorage2DEXT(GLenum target, GLsizei l
     EVENT(
         "(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = "
         "%d, GLsizei height = %d)",
         target, levels, internalformat, width, height);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::TexStorage2DEXT>(target, levels, internalformat, width,
-                                                           height);
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::TexStorage2DEXT>(targetPacked, levels, internalformat,
+                                                           width, height);
 
         if (context->skipValidation() ||
-            ValidateTexStorage2DEXT(context, target, levels, internalformat, width, height))
+            ValidateTexStorage2DEXT(context, targetPacked, levels, internalformat, width, height))
         {
-            context->texStorage2D(target, levels, internalformat, width, height);
+            context->texStorage2D(targetPacked, levels, internalformat, width, height);
         }
     }
 }
 
 void GL_APIENTRY TexStorage3DEXT(GLenum target,
                                  GLsizei levels,
                                  GLenum internalformat,
                                  GLsizei width,
@@ -649,23 +650,25 @@ void GL_APIENTRY TexStorage3DEXT(GLenum 
     EVENT(
         "(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = "
         "%d, GLsizei height = %d, GLsizei depth = %d)",
         target, levels, internalformat, width, height, depth);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::TexStorage3DEXT>(target, levels, internalformat, width,
-                                                           height, depth);
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::TexStorage3DEXT>(targetPacked, levels, internalformat,
+                                                           width, height, depth);
 
         if (context->skipValidation() ||
-            ValidateTexStorage3DEXT(context, target, levels, internalformat, width, height, depth))
+            ValidateTexStorage3DEXT(context, targetPacked, levels, internalformat, width, height,
+                                    depth))
         {
-            context->texStorage3D(target, levels, internalformat, width, height, depth);
+            context->texStorage3D(targetPacked, levels, internalformat, width, height, depth);
         }
     }
 }
 
 // GL_KHR_debug
 void GL_APIENTRY DebugMessageCallbackKHR(GLDEBUGPROCKHR callback, const void *userParam)
 {
     EVENT("(GLDEBUGPROCKHR callback = 0x%0.8p, const void *userParam = 0x%0.8p)", callback,
@@ -1041,21 +1044,23 @@ void GL_APIENTRY EGLImageTargetRenderbuf
 
 void GL_APIENTRY EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
 {
     EVENT("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::EGLImageTargetTexture2DOES>(target, image);
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::EGLImageTargetTexture2DOES>(targetPacked, image);
 
-        if (context->skipValidation() || ValidateEGLImageTargetTexture2DOES(context, target, image))
+        if (context->skipValidation() ||
+            ValidateEGLImageTargetTexture2DOES(context, targetPacked, image))
         {
-            context->eGLImageTargetTexture2D(target, image);
+            context->eGLImageTargetTexture2D(targetPacked, image);
         }
     }
 }
 
 // GL_OES_draw_texture
 void GL_APIENTRY DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
 {
     EVENT(
@@ -1187,16 +1192,302 @@ void GL_APIENTRY DrawTexxvOES(const GLfi
 
         if (context->skipValidation() || ValidateDrawTexxvOES(context, coords))
         {
             context->drawTexxv(coords);
         }
     }
 }
 
+// GL_OES_framebuffer_object
+void GL_APIENTRY BindFramebufferOES(GLenum target, GLuint framebuffer)
+{
+    EVENT("(GLenum target = 0x%X, GLuint framebuffer = %u)", target, framebuffer);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::BindFramebufferOES>(target, framebuffer);
+
+        if (context->skipValidation() || ValidateBindFramebufferOES(context, target, framebuffer))
+        {
+            context->bindFramebuffer(target, framebuffer);
+        }
+    }
+}
+
+void GL_APIENTRY BindRenderbufferOES(GLenum target, GLuint renderbuffer)
+{
+    EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %u)", target, renderbuffer);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::BindRenderbufferOES>(target, renderbuffer);
+
+        if (context->skipValidation() || ValidateBindRenderbufferOES(context, target, renderbuffer))
+        {
+            context->bindRenderbuffer(target, renderbuffer);
+        }
+    }
+}
+
+GLenum GL_APIENTRY CheckFramebufferStatusOES(GLenum target)
+{
+    EVENT("(GLenum target = 0x%X)", target);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::CheckFramebufferStatusOES>(target);
+
+        if (context->skipValidation() || ValidateCheckFramebufferStatusOES(context, target))
+        {
+            return context->checkFramebufferStatus(target);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::CheckFramebufferStatusOES, GLenum>();
+}
+
+void GL_APIENTRY DeleteFramebuffersOES(GLsizei n, const GLuint *framebuffers)
+{
+    EVENT("(GLsizei n = %d, const GLuint *framebuffers = 0x%0.8p)", n, framebuffers);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DeleteFramebuffersOES>(n, framebuffers);
+
+        if (context->skipValidation() || ValidateDeleteFramebuffersOES(context, n, framebuffers))
+        {
+            context->deleteFramebuffers(n, framebuffers);
+        }
+    }
+}
+
+void GL_APIENTRY DeleteRenderbuffersOES(GLsizei n, const GLuint *renderbuffers)
+{
+    EVENT("(GLsizei n = %d, const GLuint *renderbuffers = 0x%0.8p)", n, renderbuffers);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DeleteRenderbuffersOES>(n, renderbuffers);
+
+        if (context->skipValidation() || ValidateDeleteRenderbuffersOES(context, n, renderbuffers))
+        {
+            context->deleteRenderbuffers(n, renderbuffers);
+        }
+    }
+}
+
+void GL_APIENTRY FramebufferRenderbufferOES(GLenum target,
+                                            GLenum attachment,
+                                            GLenum renderbuffertarget,
+                                            GLuint renderbuffer)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, GLuint "
+        "renderbuffer = %u)",
+        target, attachment, renderbuffertarget, renderbuffer);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::FramebufferRenderbufferOES>(
+            target, attachment, renderbuffertarget, renderbuffer);
+
+        if (context->skipValidation() ||
+            ValidateFramebufferRenderbufferOES(context, target, attachment, renderbuffertarget,
+                                               renderbuffer))
+        {
+            context->framebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
+        }
+    }
+}
+
+void GL_APIENTRY FramebufferTexture2DOES(GLenum target,
+                                         GLenum attachment,
+                                         GLenum textarget,
+                                         GLuint texture,
+                                         GLint level)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, GLuint texture "
+        "= %u, GLint level = %d)",
+        target, attachment, textarget, texture, level);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        TextureTarget textargetPacked = FromGLenum<TextureTarget>(textarget);
+        context->gatherParams<EntryPoint::FramebufferTexture2DOES>(target, attachment,
+                                                                   textargetPacked, texture, level);
+
+        if (context->skipValidation() ||
+            ValidateFramebufferTexture2DOES(context, target, attachment, textargetPacked, texture,
+                                            level))
+        {
+            context->framebufferTexture2D(target, attachment, textargetPacked, texture, level);
+        }
+    }
+}
+
+void GL_APIENTRY GenFramebuffersOES(GLsizei n, GLuint *framebuffers)
+{
+    EVENT("(GLsizei n = %d, GLuint *framebuffers = 0x%0.8p)", n, framebuffers);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GenFramebuffersOES>(n, framebuffers);
+
+        if (context->skipValidation() || ValidateGenFramebuffersOES(context, n, framebuffers))
+        {
+            context->genFramebuffers(n, framebuffers);
+        }
+    }
+}
+
+void GL_APIENTRY GenRenderbuffersOES(GLsizei n, GLuint *renderbuffers)
+{
+    EVENT("(GLsizei n = %d, GLuint *renderbuffers = 0x%0.8p)", n, renderbuffers);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GenRenderbuffersOES>(n, renderbuffers);
+
+        if (context->skipValidation() || ValidateGenRenderbuffersOES(context, n, renderbuffers))
+        {
+            context->genRenderbuffers(n, renderbuffers);
+        }
+    }
+}
+
+void GL_APIENTRY GenerateMipmapOES(GLenum target)
+{
+    EVENT("(GLenum target = 0x%X)", target);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        TextureType targetPacked = FromGLenum<TextureType>(target);
+        context->gatherParams<EntryPoint::GenerateMipmapOES>(targetPacked);
+
+        if (context->skipValidation() || ValidateGenerateMipmapOES(context, targetPacked))
+        {
+            context->generateMipmap(targetPacked);
+        }
+    }
+}
+
+void GL_APIENTRY GetFramebufferAttachmentParameterivOES(GLenum target,
+                                                        GLenum attachment,
+                                                        GLenum pname,
+                                                        GLint *params)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint *params = "
+        "0x%0.8p)",
+        target, attachment, pname, params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetFramebufferAttachmentParameterivOES>(
+            target, attachment, pname, params);
+
+        if (context->skipValidation() || ValidateGetFramebufferAttachmentParameterivOES(
+                                             context, target, attachment, pname, params))
+        {
+            context->getFramebufferAttachmentParameteriv(target, attachment, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint *params)
+{
+    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname,
+          params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetRenderbufferParameterivOES>(target, pname, params);
+
+        if (context->skipValidation() ||
+            ValidateGetRenderbufferParameterivOES(context, target, pname, params))
+        {
+            context->getRenderbufferParameteriv(target, pname, params);
+        }
+    }
+}
+
+GLboolean GL_APIENTRY IsFramebufferOES(GLuint framebuffer)
+{
+    EVENT("(GLuint framebuffer = %u)", framebuffer);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::IsFramebufferOES>(framebuffer);
+
+        if (context->skipValidation() || ValidateIsFramebufferOES(context, framebuffer))
+        {
+            return context->isFramebuffer(framebuffer);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::IsFramebufferOES, GLboolean>();
+}
+
+GLboolean GL_APIENTRY IsRenderbufferOES(GLuint renderbuffer)
+{
+    EVENT("(GLuint renderbuffer = %u)", renderbuffer);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::IsRenderbufferOES>(renderbuffer);
+
+        if (context->skipValidation() || ValidateIsRenderbufferOES(context, renderbuffer))
+        {
+            return context->isRenderbuffer(renderbuffer);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::IsRenderbufferOES, GLboolean>();
+}
+
+void GL_APIENTRY RenderbufferStorageOES(GLenum target,
+                                        GLenum internalformat,
+                                        GLsizei width,
+                                        GLsizei height)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = "
+        "%d)",
+        target, internalformat, width, height);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::RenderbufferStorageOES>(target, internalformat, width,
+                                                                  height);
+
+        if (context->skipValidation() ||
+            ValidateRenderbufferStorageOES(context, target, internalformat, width, height))
+        {
+            context->renderbufferStorage(target, internalformat, width, height);
+        }
+    }
+}
+
 // GL_OES_get_program_binary
 void GL_APIENTRY GetProgramBinaryOES(GLuint program,
                                      GLsizei bufSize,
                                      GLsizei *length,
                                      GLenum *binaryFormat,
                                      void *binary)
 {
     EVENT(
@@ -1404,16 +1695,167 @@ GLbitfield GL_APIENTRY QueryMatrixxOES(G
         {
             return context->queryMatrixx(mantissa, exponent);
         }
     }
 
     return GetDefaultReturnValue<EntryPoint::QueryMatrixxOES, GLbitfield>();
 }
 
+// GL_OES_texture_cube_map
+void GL_APIENTRY GetTexGenfvOES(GLenum coord, GLenum pname, GLfloat *params)
+{
+    EVENT("(GLenum coord = 0x%X, GLenum pname = 0x%X, GLfloat *params = 0x%0.8p)", coord, pname,
+          params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetTexGenfvOES>(coord, pname, params);
+
+        if (context->skipValidation() || ValidateGetTexGenfvOES(context, coord, pname, params))
+        {
+            context->getTexGenfv(coord, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY GetTexGenivOES(GLenum coord, GLenum pname, GLint *params)
+{
+    EVENT("(GLenum coord = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", coord, pname,
+          params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetTexGenivOES>(coord, pname, params);
+
+        if (context->skipValidation() || ValidateGetTexGenivOES(context, coord, pname, params))
+        {
+            context->getTexGeniv(coord, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY GetTexGenxvOES(GLenum coord, GLenum pname, GLfixed *params)
+{
+    EVENT("(GLenum coord = 0x%X, GLenum pname = 0x%X, GLfixed *params = 0x%0.8p)", coord, pname,
+          params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetTexGenxvOES>(coord, pname, params);
+
+        if (context->skipValidation() || ValidateGetTexGenxvOES(context, coord, pname, params))
+        {
+            context->getTexGenxv(coord, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY TexGenfOES(GLenum coord, GLenum pname, GLfloat param)
+{
+    EVENT("(GLenum coord = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", coord, pname, param);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::TexGenfOES>(coord, pname, param);
+
+        if (context->skipValidation() || ValidateTexGenfOES(context, coord, pname, param))
+        {
+            context->texGenf(coord, pname, param);
+        }
+    }
+}
+
+void GL_APIENTRY TexGenfvOES(GLenum coord, GLenum pname, const GLfloat *params)
+{
+    EVENT("(GLenum coord = 0x%X, GLenum pname = 0x%X, const GLfloat *params = 0x%0.8p)", coord,
+          pname, params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::TexGenfvOES>(coord, pname, params);
+
+        if (context->skipValidation() || ValidateTexGenfvOES(context, coord, pname, params))
+        {
+            context->texGenfv(coord, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY TexGeniOES(GLenum coord, GLenum pname, GLint param)
+{
+    EVENT("(GLenum coord = 0x%X, GLenum pname = 0x%X, GLint param = %d)", coord, pname, param);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::TexGeniOES>(coord, pname, param);
+
+        if (context->skipValidation() || ValidateTexGeniOES(context, coord, pname, param))
+        {
+            context->texGeni(coord, pname, param);
+        }
+    }
+}
+
+void GL_APIENTRY TexGenivOES(GLenum coord, GLenum pname, const GLint *params)
+{
+    EVENT("(GLenum coord = 0x%X, GLenum pname = 0x%X, const GLint *params = 0x%0.8p)", coord, pname,
+          params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::TexGenivOES>(coord, pname, params);
+
+        if (context->skipValidation() || ValidateTexGenivOES(context, coord, pname, params))
+        {
+            context->texGeniv(coord, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY TexGenxOES(GLenum coord, GLenum pname, GLfixed param)
+{
+    EVENT("(GLenum coord = 0x%X, GLenum pname = 0x%X, GLfixed param = 0x%X)", coord, pname, param);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::TexGenxOES>(coord, pname, param);
+
+        if (context->skipValidation() || ValidateTexGenxOES(context, coord, pname, param))
+        {
+            context->texGenx(coord, pname, param);
+        }
+    }
+}
+
+void GL_APIENTRY TexGenxvOES(GLenum coord, GLenum pname, const GLfixed *params)
+{
+    EVENT("(GLenum coord = 0x%X, GLenum pname = 0x%X, const GLfixed *params = 0x%0.8p)", coord,
+          pname, params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::TexGenxvOES>(coord, pname, params);
+
+        if (context->skipValidation() || ValidateTexGenxvOES(context, coord, pname, params))
+        {
+            context->texGenxv(coord, pname, params);
+        }
+    }
+}
+
 // GL_OES_vertex_array_object
 void GL_APIENTRY BindVertexArrayOES(GLuint array)
 {
     EVENT("(GLuint array = %u)", array);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
--- a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_ext_autogen.h
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_ext_autogen.h
@@ -195,16 +195,48 @@ ANGLE_EXPORT void GL_APIENTRY DrawTexiOE
 ANGLE_EXPORT void GL_APIENTRY DrawTexivOES(const GLint *coords);
 ANGLE_EXPORT void GL_APIENTRY
 DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height);
 ANGLE_EXPORT void GL_APIENTRY DrawTexsvOES(const GLshort *coords);
 ANGLE_EXPORT void GL_APIENTRY
 DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height);
 ANGLE_EXPORT void GL_APIENTRY DrawTexxvOES(const GLfixed *coords);
 
+// GL_OES_framebuffer_object
+ANGLE_EXPORT void GL_APIENTRY BindFramebufferOES(GLenum target, GLuint framebuffer);
+ANGLE_EXPORT void GL_APIENTRY BindRenderbufferOES(GLenum target, GLuint renderbuffer);
+ANGLE_EXPORT GLenum GL_APIENTRY CheckFramebufferStatusOES(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY DeleteFramebuffersOES(GLsizei n, const GLuint *framebuffers);
+ANGLE_EXPORT void GL_APIENTRY DeleteRenderbuffersOES(GLsizei n, const GLuint *renderbuffers);
+ANGLE_EXPORT void GL_APIENTRY FramebufferRenderbufferOES(GLenum target,
+                                                         GLenum attachment,
+                                                         GLenum renderbuffertarget,
+                                                         GLuint renderbuffer);
+ANGLE_EXPORT void GL_APIENTRY FramebufferTexture2DOES(GLenum target,
+                                                      GLenum attachment,
+                                                      GLenum textarget,
+                                                      GLuint texture,
+                                                      GLint level);
+ANGLE_EXPORT void GL_APIENTRY GenFramebuffersOES(GLsizei n, GLuint *framebuffers);
+ANGLE_EXPORT void GL_APIENTRY GenRenderbuffersOES(GLsizei n, GLuint *renderbuffers);
+ANGLE_EXPORT void GL_APIENTRY GenerateMipmapOES(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY GetFramebufferAttachmentParameterivOES(GLenum target,
+                                                                     GLenum attachment,
+                                                                     GLenum pname,
+                                                                     GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GetRenderbufferParameterivOES(GLenum target,
+                                                            GLenum pname,
+                                                            GLint *params);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsFramebufferOES(GLuint framebuffer);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsRenderbufferOES(GLuint renderbuffer);
+ANGLE_EXPORT void GL_APIENTRY RenderbufferStorageOES(GLenum target,
+                                                     GLenum internalformat,
+                                                     GLsizei width,
+                                                     GLsizei height);
+
 // GL_OES_get_program_binary
 ANGLE_EXPORT void GL_APIENTRY GetProgramBinaryOES(GLuint program,
                                                   GLsizei bufSize,
                                                   GLsizei *length,
                                                   GLenum *binaryFormat,
                                                   void *binary);
 ANGLE_EXPORT void GL_APIENTRY ProgramBinaryOES(GLuint program,
                                                GLenum binaryFormat,
@@ -229,16 +261,27 @@ ANGLE_EXPORT void GL_APIENTRY WeightPoin
                                                const void *pointer);
 
 // GL_OES_point_size_array
 ANGLE_EXPORT void GL_APIENTRY PointSizePointerOES(GLenum type, GLsizei stride, const void *pointer);
 
 // GL_OES_query_matrix
 ANGLE_EXPORT GLbitfield GL_APIENTRY QueryMatrixxOES(GLfixed *mantissa, GLint *exponent);
 
+// GL_OES_texture_cube_map
+ANGLE_EXPORT void GL_APIENTRY GetTexGenfvOES(GLenum coord, GLenum pname, GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GetTexGenivOES(GLenum coord, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GetTexGenxvOES(GLenum coord, GLenum pname, GLfixed *params);
+ANGLE_EXPORT void GL_APIENTRY TexGenfOES(GLenum coord, GLenum pname, GLfloat param);
+ANGLE_EXPORT void GL_APIENTRY TexGenfvOES(GLenum coord, GLenum pname, const GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY TexGeniOES(GLenum coord, GLenum pname, GLint param);
+ANGLE_EXPORT void GL_APIENTRY TexGenivOES(GLenum coord, GLenum pname, const GLint *params);
+ANGLE_EXPORT void GL_APIENTRY TexGenxOES(GLenum coord, GLenum pname, GLfixed param);
+ANGLE_EXPORT void GL_APIENTRY TexGenxvOES(GLenum coord, GLenum pname, const GLfixed *params);
+
 // GL_OES_vertex_array_object
 ANGLE_EXPORT void GL_APIENTRY BindVertexArrayOES(GLuint array);
 ANGLE_EXPORT void GL_APIENTRY DeleteVertexArraysOES(GLsizei n, const GLuint *arrays);
 ANGLE_EXPORT void GL_APIENTRY GenVertexArraysOES(GLsizei n, GLuint *arrays);
 ANGLE_EXPORT GLboolean GL_APIENTRY IsVertexArrayOES(GLuint array);
 }  // namespace gl
 
 #endif  // LIBGLESV2_ENTRY_POINTS_GLES_EXT_AUTOGEN_H_
--- a/gfx/angle/checkout/src/libGLESv2/proc_table.h
+++ b/gfx/angle/checkout/src/libGLESv2/proc_table.h
@@ -6,16 +6,17 @@
 // getProcAddress loader table:
 //   Mapping from a string entry point name to function address.
 //
 
 #ifndef LIBGLESV2_PROC_TABLE_H_
 #define LIBGLESV2_PROC_TABLE_H_
 
 #include <EGL/egl.h>
+#include <stddef.h>
 #include <utility>
 
 namespace egl
 {
 using ProcEntry = std::pair<const char *, __eglMustCastToProperFunctionPointerType>;
 
 extern ProcEntry g_procTable[];
 extern size_t g_numProcs;
--- a/gfx/angle/checkout/src/third_party/compiler/ArrayBoundsClamper.cpp
+++ b/gfx/angle/checkout/src/third_party/compiler/ArrayBoundsClamper.cpp
@@ -20,17 +20,17 @@
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "third_party/compiler/ArrayBoundsClamper.h"
 
-#include "compiler/translator/IntermTraverse.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
 
 // The built-in 'clamp' instruction only accepts floats and returns a float.  I
 // iterated a few times with our driver team who examined the output from our
 // compiler - they said the multiple casts generates more code than a single
 // function call.  An inline ternary operator might have been better, but since
 // the index value might be an expression itself, we'd have to make temporary
 // variables to avoid evaluating the expression multiple times.  And making
 // temporary variables was difficult because ANGLE would then need to make more
--- a/gfx/angle/targets/libANGLE/moz.build
+++ b/gfx/angle/targets/libANGLE/moz.build
@@ -111,34 +111,38 @@ SOURCES += [
     '../../checkout/src/common/event_tracer.cpp',
     '../../checkout/src/libANGLE/angletypes.cpp',
     '../../checkout/src/libANGLE/AttributeMap.cpp',
     '../../checkout/src/libANGLE/Buffer.cpp',
     '../../checkout/src/libANGLE/Caps.cpp',
     '../../checkout/src/libANGLE/Compiler.cpp',
     '../../checkout/src/libANGLE/Config.cpp',
     '../../checkout/src/libANGLE/Context.cpp',
+    '../../checkout/src/libANGLE/Context_gles_1_0.cpp',
     '../../checkout/src/libANGLE/ContextState.cpp',
     '../../checkout/src/libANGLE/Debug.cpp',
     '../../checkout/src/libANGLE/Device.cpp',
     '../../checkout/src/libANGLE/Display.cpp',
     '../../checkout/src/libANGLE/Error.cpp',
     '../../checkout/src/libANGLE/es3_copy_conversion_table_autogen.cpp',
     '../../checkout/src/libANGLE/Fence.cpp',
     '../../checkout/src/libANGLE/format_map_autogen.cpp',
     '../../checkout/src/libANGLE/formatutils.cpp',
     '../../checkout/src/libANGLE/Framebuffer.cpp',
     '../../checkout/src/libANGLE/FramebufferAttachment.cpp',
+    '../../checkout/src/libANGLE/GLES1State.cpp',
     '../../checkout/src/libANGLE/HandleAllocator.cpp',
     '../../checkout/src/libANGLE/HandleRangeAllocator.cpp',
     '../../checkout/src/libANGLE/Image.cpp',
     '../../checkout/src/libANGLE/ImageIndex.cpp',
     '../../checkout/src/libANGLE/IndexRangeCache.cpp',
     '../../checkout/src/libANGLE/LoggingAnnotator.cpp',
     '../../checkout/src/libANGLE/MemoryProgramCache.cpp',
+    '../../checkout/src/libANGLE/Observer.cpp',
+    '../../checkout/src/libANGLE/PackedGLEnums.cpp',
     '../../checkout/src/libANGLE/PackedGLEnums_autogen.cpp',
     '../../checkout/src/libANGLE/params.cpp',
     '../../checkout/src/libANGLE/Path.cpp',
     '../../checkout/src/libANGLE/Platform.cpp',
     '../../checkout/src/libANGLE/Program.cpp',
     '../../checkout/src/libANGLE/ProgramLinkedResources.cpp',
     '../../checkout/src/libANGLE/ProgramPipeline.cpp',
     '../../checkout/src/libANGLE/Query.cpp',
@@ -228,17 +232,16 @@ SOURCES += [
     '../../checkout/src/libANGLE/renderer/Format_table_autogen.cpp',
     '../../checkout/src/libANGLE/renderer/load_functions_table_autogen.cpp',
     '../../checkout/src/libANGLE/renderer/renderer_utils.cpp',
     '../../checkout/src/libANGLE/renderer/SurfaceImpl.cpp',
     '../../checkout/src/libANGLE/renderer/TextureImpl.cpp',
     '../../checkout/src/libANGLE/ResourceManager.cpp',
     '../../checkout/src/libANGLE/Sampler.cpp',
     '../../checkout/src/libANGLE/Shader.cpp',
-    '../../checkout/src/libANGLE/signal_utils.cpp',
     '../../checkout/src/libANGLE/State.cpp',
     '../../checkout/src/libANGLE/Stream.cpp',
     '../../checkout/src/libANGLE/Surface.cpp',
     '../../checkout/src/libANGLE/Texture.cpp',
     '../../checkout/src/libANGLE/Thread.cpp',
     '../../checkout/src/libANGLE/TransformFeedback.cpp',
     '../../checkout/src/libANGLE/Uniform.cpp',
     '../../checkout/src/libANGLE/validationEGL.cpp',
--- a/gfx/angle/targets/translator/moz.build
+++ b/gfx/angle/targets/translator/moz.build
@@ -100,126 +100,125 @@ LOCAL_INCLUDES += [
 #    '/we4800',
 #    '/we4838',
 #    '/WX',
 #    '/Zc:sizedDealloc-',
 #    '/Zi',
 #]
 
 SOURCES += [
-    '../../checkout/src/compiler/translator/AddAndTrueToLoopCondition.cpp',
-    '../../checkout/src/compiler/translator/AddDefaultReturnStatements.cpp',
-    '../../checkout/src/compiler/translator/ArrayReturnValueToOutParameter.cpp',
     '../../checkout/src/compiler/translator/ASTMetadataHLSL.cpp',
     '../../checkout/src/compiler/translator/blocklayout.cpp',
     '../../checkout/src/compiler/translator/blocklayoutHLSL.cpp',
-    '../../checkout/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp',
     '../../checkout/src/compiler/translator/BuiltInFunctionEmulator.cpp',
     '../../checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp',
     '../../checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp',
     '../../checkout/src/compiler/translator/CallDAG.cpp',
-    '../../checkout/src/compiler/translator/ClampFragDepth.cpp',
-    '../../checkout/src/compiler/translator/ClampPointSize.cpp',
     '../../checkout/src/compiler/translator/CodeGen.cpp',
     '../../checkout/src/compiler/translator/CollectVariables.cpp',
     '../../checkout/src/compiler/translator/Compiler.cpp',
     '../../checkout/src/compiler/translator/ConstantUnion.cpp',
     '../../checkout/src/compiler/translator/Declarator.cpp',
-    '../../checkout/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp',
-    '../../checkout/src/compiler/translator/DeferGlobalInitializers.cpp',
     '../../checkout/src/compiler/translator/Diagnostics.cpp',
     '../../checkout/src/compiler/translator/DirectiveHandler.cpp',
     '../../checkout/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp',
-    '../../checkout/src/compiler/translator/EmulateGLFragColorBroadcast.cpp',
-    '../../checkout/src/compiler/translator/EmulatePrecision.cpp',
-    '../../checkout/src/compiler/translator/ExpandIntegerPowExpressions.cpp',
     '../../checkout/src/compiler/translator/ExtensionBehavior.cpp',
     '../../checkout/src/compiler/translator/ExtensionGLSL.cpp',
-    '../../checkout/src/compiler/translator/FindMain.cpp',
-    '../../checkout/src/compiler/translator/FindSymbolNode.cpp',
     '../../checkout/src/compiler/translator/FlagStd140Structs.cpp',
-    '../../checkout/src/compiler/translator/FoldExpressions.cpp',
     '../../checkout/src/compiler/translator/FunctionLookup.cpp',
     '../../checkout/src/compiler/translator/glslang_lex.cpp',
     '../../checkout/src/compiler/translator/glslang_tab.cpp',
     '../../checkout/src/compiler/translator/HashNames.cpp',
     '../../checkout/src/compiler/translator/ImageFunctionHLSL.cpp',
     '../../checkout/src/compiler/translator/ImmutableString.cpp',
     '../../checkout/src/compiler/translator/ImmutableStringBuilder.cpp',
     '../../checkout/src/compiler/translator/InfoSink.cpp',
     '../../checkout/src/compiler/translator/Initialize.cpp',
     '../../checkout/src/compiler/translator/InitializeDll.cpp',
-    '../../checkout/src/compiler/translator/InitializeVariables.cpp',
     '../../checkout/src/compiler/translator/IntermNode.cpp',
-    '../../checkout/src/compiler/translator/IntermNode_util.cpp',
-    '../../checkout/src/compiler/translator/IntermNodePatternMatcher.cpp',
-    '../../checkout/src/compiler/translator/IntermTraverse.cpp',
     '../../checkout/src/compiler/translator/IsASTDepthBelowLimit.cpp',
     '../../checkout/src/compiler/translator/Operator.cpp',
     '../../checkout/src/compiler/translator/OutputESSL.cpp',
     '../../checkout/src/compiler/translator/OutputGLSL.cpp',
     '../../checkout/src/compiler/translator/OutputGLSLBase.cpp',
     '../../checkout/src/compiler/translator/OutputHLSL.cpp',
     '../../checkout/src/compiler/translator/OutputTree.cpp',
     '../../checkout/src/compiler/translator/ParseContext.cpp',
     '../../checkout/src/compiler/translator/PoolAlloc.cpp',
-    '../../checkout/src/compiler/translator/PruneNoOps.cpp',
     '../../checkout/src/compiler/translator/QualifierTypes.cpp',
-    '../../checkout/src/compiler/translator/RecordConstantPrecision.cpp',
-    '../../checkout/src/compiler/translator/RegenerateStructNames.cpp',
-    '../../checkout/src/compiler/translator/RemoveArrayLengthMethod.cpp',
-    '../../checkout/src/compiler/translator/RemoveDynamicIndexing.cpp',
-    '../../checkout/src/compiler/translator/RemoveEmptySwitchStatements.cpp',
-    '../../checkout/src/compiler/translator/RemoveInvariantDeclaration.cpp',
-    '../../checkout/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.cpp',
-    '../../checkout/src/compiler/translator/RemovePow.cpp',
-    '../../checkout/src/compiler/translator/RemoveSwitchFallThrough.cpp',
-    '../../checkout/src/compiler/translator/RemoveUnreferencedVariables.cpp',
-    '../../checkout/src/compiler/translator/ReplaceVariable.cpp',
-    '../../checkout/src/compiler/translator/RewriteDoWhile.cpp',
-    '../../checkout/src/compiler/translator/RewriteElseBlocks.cpp',
-    '../../checkout/src/compiler/translator/RewriteTexelFetchOffset.cpp',
-    '../../checkout/src/compiler/translator/RewriteUnaryMinusOperatorFloat.cpp',
-    '../../checkout/src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp',
-    '../../checkout/src/compiler/translator/RunAtTheEndOfShader.cpp',
-    '../../checkout/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp',
-    '../../checkout/src/compiler/translator/SeparateArrayConstructorStatements.cpp',
-    '../../checkout/src/compiler/translator/SeparateArrayInitialization.cpp',
-    '../../checkout/src/compiler/translator/SeparateDeclarations.cpp',
-    '../../checkout/src/compiler/translator/SeparateExpressionsReturningArrays.cpp',
     '../../checkout/src/compiler/translator/ShaderLang.cpp',
     '../../checkout/src/compiler/translator/ShaderVars.cpp',
-    '../../checkout/src/compiler/translator/SimplifyLoopConditions.cpp',
-    '../../checkout/src/compiler/translator/SplitSequenceOperator.cpp',
-    '../../checkout/src/compiler/translator/StaticType.cpp',
     '../../checkout/src/compiler/translator/StructureHLSL.cpp',
     '../../checkout/src/compiler/translator/Symbol.cpp',
     '../../checkout/src/compiler/translator/SymbolTable.cpp',
+    '../../checkout/src/compiler/translator/SymbolTable_autogen.cpp',
     '../../checkout/src/compiler/translator/SymbolUniqueId.cpp',
     '../../checkout/src/compiler/translator/TextureFunctionHLSL.cpp',
     '../../checkout/src/compiler/translator/TranslatorESSL.cpp',
     '../../checkout/src/compiler/translator/TranslatorGLSL.cpp',
     '../../checkout/src/compiler/translator/TranslatorHLSL.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/AddAndTrueToLoopCondition.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/AddDefaultReturnStatements.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/ArrayReturnValueToOutParameter.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/BreakVariableAliasingInInnerLoops.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/ClampFragDepth.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/ClampPointSize.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/EmulatePrecision.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/ExpandIntegerPowExpressions.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/FoldExpressions.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/InitializeVariables.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/PruneEmptyCases.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/PruneNoOps.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/RegenerateStructNames.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/RemovePow.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/RemoveSwitchFallThrough.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/RewriteDoWhile.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/RewriteElseBlocks.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/RewriteUnaryMinusOperatorFloat.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/RewriteUnaryMinusOperatorInt.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/SeparateArrayConstructorStatements.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/SeparateArrayInitialization.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/SeparateDeclarations.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/SeparateExpressionsReturningArrays.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/UnfoldShortCircuitAST.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/UnfoldShortCircuitToIf.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/UseInterfaceBlockFields.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/VectorizeVectorScalarArithmetic.cpp',
+    '../../checkout/src/compiler/translator/tree_ops/WrapSwitchStatementsInBlocks.cpp',
+    '../../checkout/src/compiler/translator/tree_util/FindMain.cpp',
+    '../../checkout/src/compiler/translator/tree_util/FindSymbolNode.cpp',
+    '../../checkout/src/compiler/translator/tree_util/IntermNode_util.cpp',
+    '../../checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.cpp',
+    '../../checkout/src/compiler/translator/tree_util/IntermTraverse.cpp',
+    '../../checkout/src/compiler/translator/tree_util/ReplaceVariable.cpp',
+    '../../checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.cpp',
     '../../checkout/src/compiler/translator/Types.cpp',
-    '../../checkout/src/compiler/translator/UnfoldShortCircuitAST.cpp',
-    '../../checkout/src/compiler/translator/UnfoldShortCircuitToIf.cpp',
     '../../checkout/src/compiler/translator/UniformHLSL.cpp',
-    '../../checkout/src/compiler/translator/UseInterfaceBlockFields.cpp',
     '../../checkout/src/compiler/translator/util.cpp',
     '../../checkout/src/compiler/translator/UtilsHLSL.cpp',
     '../../checkout/src/compiler/translator/ValidateGlobalInitializer.cpp',
     '../../checkout/src/compiler/translator/ValidateLimitations.cpp',
     '../../checkout/src/compiler/translator/ValidateMaxParameters.cpp',
     '../../checkout/src/compiler/translator/ValidateOutputs.cpp',
     '../../checkout/src/compiler/translator/ValidateSwitch.cpp',
     '../../checkout/src/compiler/translator/ValidateVaryingLocations.cpp',
     '../../checkout/src/compiler/translator/VariablePacker.cpp',
-    '../../checkout/src/compiler/translator/VectorizeVectorScalarArithmetic.cpp',
     '../../checkout/src/compiler/translator/VersionGLSL.cpp',
-    '../../checkout/src/compiler/translator/WrapSwitchStatementsInBlocks.cpp',
     '../../checkout/src/third_party/compiler/ArrayBoundsClamper.cpp',
 ]
 
 USE_LIBS += [
     'angle_common',
     'preprocessor',
 ]